【发布时间】:2012-04-19 15:25:03
【问题描述】:
H 我试图弄清楚为什么两个相似但略有不同的 SQL 查询在运行它们所花费的时间之间存在如此大的差异。 我希望根据以下两个示例和报告的时间提供意见。
第一个查询如下,运行大约需要 115 - 154 秒。
SELECT * FROM
(
SELECT a.*, ROWNUM rnum
FROM
(
SELECT ERR_ID, ERR_CREATED_BY,TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI'),
ERR_SOURCE, ERR_DETAIL
FROM tdsys_errors err
WHERE ERR_SOURCE = 'Online Transaction'
ORDER BY ERR_ID DESC
) a
WHERE ROWNUM <= 25
)
WHERE rnum > 0;
第二个查询在“ORDER BY ERR_ID DESC”块的位置方面略有变化,运行大约需要0.07秒
SELECT * FROM
(
SELECT a.*, ROWNUM rnum
FROM
(
SELECT ERR_ID, ERR_CREATED_BY,TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI'),
ERR_SOURCE, ERR_DETAIL
FROM tdsys_errors err
WHERE ERR_SOURCE = 'Online Transaction'
) a
WHERE ROWNUM <= 25
)
WHERE rnum > 0
ORDER BY ERR_ID DESC;
我猜第二个查询是在结果到达之后排序的,第一个查询尝试一次完成所有操作。 我想知道这是一个 SQL 最佳实践案例吗?为什么会有这样的差异?
谢谢
【问题讨论】:
-
看起来您在那里有不必要的嵌套级别。在第一个(正确的)代码块中,您可以删除外部查询。此外,
WHERE rownum > 0总是评估为 true 并且是多余的。 -
我也几乎总是选择按创建日期而不是 id 排序。据推测您正在寻找最新的错误。
-
整个声明
WHERE rnum > 0是不必要的,因为我很怀疑是否有可能获得 negative 行号。一个我不太确定的“0”数字(到目前为止我看到的所有内容都从 1 开始,但我不使用 mySQL),但无论如何你可能想要那一行。如其他地方所述,在第二个查询中,您将获得 25 个 random 行(与内部WHERE子句匹配),这可能不是您想要的。 -
嗨,下面的大卫写了一个很好的查询来解决这个问题,我测试了它并且效果很好。我接受了 Alex'x 的回答,因为它回答了我最初的疑问并为我解决了问题。