Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么CTE比Temp表慢?_Sql_Sql Server_Temp Tables - Fatal编程技术网

Sql 为什么CTE比Temp表慢?

Sql 为什么CTE比Temp表慢?,sql,sql-server,temp-tables,Sql,Sql Server,Temp Tables,我有一个简单的存储过程,其中有多个带有子句的 有些代码是这样的: WITH cteRowNums AS ( SELECT ROW_NUMBER() OVER(ORDER BY fcmp.EmpUserID, fcmp.WorkCellID, fcmp.ActivityTS) AS RowNumber, fcmp.ActivityTS, fcmp.ArtifactTypeID, fcmp.ServerDateID,

我有一个简单的存储过程,其中有多个带有子句的

有些代码是这样的:

WITH cteRowNums AS
(
    SELECT 
        ROW_NUMBER() OVER(ORDER BY fcmp.EmpUserID, fcmp.WorkCellID, fcmp.ActivityTS) AS RowNumber,
        fcmp.ActivityTS, 
        fcmp.ArtifactTypeID, 
        fcmp.ServerDateID, 
        fcmp.ServerHourID, 
        fcmp.EmpUserID, 
        fcmp.WorkCellID
        FROM dbo.FactCassetteMarkingProcessing fcmp
        WHERE ServerDateID >= '2007-01-01'
),
-- Make an attempt at identifying what each user did in their "session" by self-joining
cteJoinCurAndNext AS
(
SELECT
      [Current Row].ArtifactTypeID, 
      [Current Row].ServerDateID, 
      [Current Row].ServerHourID, 
      [Current Row].EmpUserID, 
      [Current Row].WorkCellID
FROM cteRowNums [Current Row] 
    LEFT OUTER JOIN cteRowNums [Next Row] ON [Next Row].RowNumber = [Current Row].RowNumber + 1
        WHERE [Current Row].ArtifactTypeID = 2
        OR ([Current Row].ArtifactTypeID = 1 AND [Next Row].ArtifactTypeID = 2 
                    AND [Current Row].EmpUserID = [Next Row].EmpUserID 
                    AND [Current Row].WorkCellID = [Next Row].WorkCellID)
),
-- Do some aggregations
cteAggregates AS    
(
SELECT 
    EmpUserID,
    ServerDateID,
    ServerHourID, 
    COUNT(NULLIF(ArtifactTypeID, 2)) AS SpecimensProcessedCount,  
    COUNT(NULLIF(ArtifactTypeID, 1)) AS BlocksProcessedCount 
    FROM cteJoinCurAndNext
    GROUP BY EmpUserID, ServerDateID, ServerHourID
)
SELECT * FROM cteAggregates
问题是大约250万行需要花费大量时间。我在40分钟时取消了执行查询

如果我用
temporary
表更改这段代码,执行速度会快得多。是否有任何方法可以仅使用CTE获得几乎相同的性能?

有两个原因

可能更重要的原因是SQLServer没有实现CTE。因此,对于每个引用,SQL Server都会重新计算整个CTE。据我所知,SQL Server也不会对执行DAG执行常见的子查询优化,因此它总是重新生成CTE(尽管每个实例的执行计划可能不同)

第二个原因是临时表具有统计信息,这些统计信息可以通知查询计划创建更好的计划

我想你可以简化逻辑。但是,您需要提出一个新问题,解释您想要做什么,以及样本数据和期望的结果