Mih*_*nut 4 sql sql-server temp-tables
我有一个简单的存储 过程,其中有多个WITH 子句。
一些代码是这样的:
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
Run Code Online (Sandbox Code Playgroud)
问题是这需要大量时间来处理大约 250 万行。我在 40 分钟取消了执行查询。
如果我用temporarytable更改这段代码,执行速度会快得多。有没有什么方法可以仅使用获得几乎相同的性能CTEs?
有两个原因。
可能更重要的原因是 SQL Server 没有实现 CTE。因此,对于每个引用,SQL Server 都会重新计算整个 CTE。据我所知,SQL Server 也没有对执行 DAG 做常见的子查询优化,所以它总是重新生成 CTES(尽管每个实例的执行计划可能不同)。
第二个原因是临时表有统计信息,这些统计信息可以通知查询计划以创建更好的计划。
我怀疑你可以简化逻辑。但是,您需要提出一个新问题,解释您想要做什么,以及示例数据和所需结果。
| 归档时间: |
|
| 查看次数: |
68 次 |
| 最近记录: |