CTE中子查询的行为

时间:2014-02-20 04:46:12

标签: sql-server tsql subquery common-table-expression

平台 - SQL Server 2008 R2 这是一个复杂的存储过程的一部分,执行时间超过5分钟,我被要求帮助排除故障

;WITH FilteredOrders AS 
    (
        --CTE definition   
    ), 
    PagedOrders AS    
    (    
      SELECT  * FROM    
      (    
        SELECT ROW_NUMBER() OVER ( order by OrderNumber asc ) AS Row,
        --Column List from FilteredOrders
        FROM FilteredOrders    
      ) AS NumberedOrders    
      WHERE NumberedOrders.Row BETWEEN 1 AND 500
    )
 SELECT * FROM PagedOrders

我在第二个CTE中删除了子查询并推荐了这个

;WITH FilteredOrders AS 
    (
        --CTE definition   
    )
    SELECT ROW_NUMBER() OVER ( order by OrderNumber asc ) AS Row,
    --Column List from FilteredOrders
    INTO #PagedOrders
    FROM FilteredOrders

SELECT  * 
FROM #PagedOrders   
WHERE #PagedOrders.Row BETWEEN 1 AND 500

现在查询在2秒内执行。虽然我讨厌承认它,但事实是我并不完全理解第二个查询给出的巨大性能提升。为什么我看到这么大的差异?

2 个答案:

答案 0 :(得分:0)

我相信每次调用CTE时都会对其进行评估。这类似于观点。但是,当您将数据插入哈希表时,它是一次性进程并避免多次执行。

这与为什么建议使用索引视图的原因相同,因为数据实际上是物理存储的,而不是在运行时进行评估。 CTE和哈希表也会出现同样的情况。

在您确定CTE查询足够快以不影响性能之前,也会在连接中避免使用CTE。

答案 1 :(得分:0)

方法1,虽然首先涉及多少行

WITH FilteredOrders AS 
    (
        select blah,blah,   ROW_NUMBER() OVER ( order by OrderNumber asc ) AS Row
from blah
    ), 

      select * FROM FilteredOrders Row BETWEEN 1 AND 500

方法2,

SELECT blah,blah, ROW_NUMBER() OVER ( order by OrderNumber asc ) AS Row,
    --Column List from FilteredOrders
    INTO #PagedOrders
    FROM [use join logic of FilteredOrders here  ]