2

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 最佳实践案例吗?为什么会有这样的差异?

谢谢

4

4 回答 4

6

您自己的总结是正确的,第一个查询按 err_id 对 tdsys_errors 中的行进行排序,取其中的前 25 个,然后返回那些。第二个查询只输出 25 行(不保证顺序),然​​后对这些随机的 25 行进行排序。

于 2012-04-19T15:27:24.030 回答
5

在第一种情况下,您选择前 25 行 - 那些最低的最高err_id。它必须从您的查询中找到所有结果,然后在知道要使用哪个 25 之前将它们全部排序,这显然需要一段时间。

在第二种情况下,您将提取无序查询返回的前 25 行,这可能是快速的,然后只对这 25 行进行排序。

您可能会从这两个查询中得到不同的结果——您当然不应该假设它们总是相同的,即使它们有时碰巧也是如此。

于 2012-04-19T15:26:57.087 回答
2

原因是第一个查询必须对tdsys_errors表中的所有行进行排序,而第二个查询只有从内部查询返回的 25 行进行排序。

请注意,两个查询的输出可能不同。

于 2012-04-19T15:26:35.277 回答
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;

希望这可以帮助。

于 2012-04-19T17:39:07.760 回答