Oracle SQL查询在查询中略有改动会导致大的结果返回时间差异

时间:2012-04-19 15:25:04

标签: sql oracle

ħ 我试图弄清楚为什么两个相似但略有不同的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最佳实践案例是我想知道的,为什么会有这样的差异?

由于

4 个答案:

答案 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;

希望这有帮助。