ħ 我试图弄清楚为什么两个相似但略有不同的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最佳实践案例是我想知道的,为什么会有这样的差异?
由于
答案 0 :(得分:6)
你自己的求和是正确的,第一个查询通过err_id对来自tdsys_errors的行进行排序,获取前25个,然后返回这些行。第二个查询只输出25行(没有保证命令)然后命令那些随机的25行。
答案 1 :(得分:5)
在第一种情况下,您选择前25行 - 最低最高err_id
。它必须从您的查询中找到所有结果,然后在知道使用哪个25之前对它们进行排序,这显然需要一段时间。
在第二种情况下,你要拉出无序查询返回的前25行,这可能是快速的,然后只排序那些。
您可能会从两个查询中得到不同的结果 - 您当然不应该假设它们总是相同的,即使它们有时恰好相同。
答案 2 :(得分:2)
原因是第一个查询必须对tdsys_errors
表中的所有行进行排序,而第二个查询只有从内部查询返回的25行才能进行排序。
请注意,两个查询的输出可能不同。
答案 3 :(得分:1)
假设您使用的是Oracle 9i或更高版本,则可以使用窗口/分析函数ROW_NUMBER()
,因此您无需使用多个子查询:
SELECT * FROM (
SELECT ERR_ID, ERR_CREATED_BY, TO_CHAR(ERR_CREATED_DATE, 'DD/MM/YYYY H24:MI')
, ERR_SOURCE, ERR_DETAIL, ROW_NUMBER() OVER (ORDER BY ERR_ID DESC) AS rnum
FROM tdsys_errors err
WHERE ERR_SOURCE = 'Online Transaction'
) WHERE rnum <= 25
ORDER BY ERR_ID DESC;
希望这有帮助。