我有 2 个不同的查询来识别重复(如下)。两个查询之间的唯一区别是一个使用 CTE,另一个使用 #Temp 表。
有谁知道为什么 CTE 比 #Temp 表快得多(0:20 秒 VS. 1:22)?
我宁愿使用 CTE,但我需要使用 CTE 运行 2 个 STATEMENTS(从 CTE 删除,然后从 CTE 插入表),但 SQL Server 只允许您在 CTE 上编写一个 STATEMENT。
查询 1:
WITH DUPS AS(
Id,
Column1,
Column2,
Column3,
RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY id)
FROM mytable
)
Select top 1 * FROM DUPS WHERE RN > 1
Run Code Online (Sandbox Code Playgroud)
查询 2:
SELECT
Id,
Column1,
Column2,
Column3,
RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY id)
INTO #DUPS
FROM mytable
Select top 1 * FROM #DUPS WHERE RN > 1
Run Code Online (Sandbox Code Playgroud)
我相信,如果您查看执行计划,您会发现 CTE 为您提供了更好的计划,因为它可以更好地利用TOP
. 临时表必须在 TempDB 中创建表,将所有数据保存到磁盘,然后选择顶部记录。如果您TOP
从两个查询中删除 ,我敢打赌您会获得更接近的性能。话虽如此,我通常希望 CTE 在像您这里这样的单次使用场景中执行临时表,因为 CTE 所做的工作比创建/插入临时表少。
这可能只是示例代码,但值得一提的是,您的结果是不确定的,因为您TOP
没有使用ORDER BY
子句。
如需进一步阅读,您应该查看此问题。这个问题的答案似乎特别适用于您的情况。
对于您问题的隐含后半部分:
既然您说您需要至少两次使用来自 CTE 的数据,那么您有四个选择:
我倾向于选择选项 2(表变量)或选项 4(定制的 CTE)方法。我不喜欢复制/粘贴 CTE 的重复和额外维护。我也喜欢在临时表上显式缩小表变量的范围。有关表变量和临时表之间差异的权威处理,请查看此答案。至于在选项 2 和 4 之间进行选择;这将取决于您的分析规定和/或您必须在哪些限制范围内工作。