【发布时间】:2012-10-22 14:34:56
【问题描述】:
我一直在试验以下(简化的)CTE。使用表变量 () 时,查询会在我取消之前运行几分钟。任何其他被注释掉的方法都会在不到一秒的时间内返回。
如果我用 INNER JOIN 替换整个 WHERE 子句,它也很快。
任何想法为什么使用表变量会运行这么慢?
FWIW:数据库包含 250 万条记录,内部查询返回 2 条记录。
CREATE TABLE #rootTempTable (RootID int PRIMARY KEY)
INSERT INTO #rootTempTable VALUES (1360);
DECLARE @rootTableVar TABLE (RootID int PRIMARY KEY);
INSERT INTO @rootTableVar VALUES (1360);
WITH My_CTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY d.DocumentID) rownum, d.DocumentID, d.Title
FROM [Document] d
WHERE d.LocationID IN
(
SELECT LocationID
FROM Location
JOIN @rootTableVar rtv ON Location.RootID = rtv.RootID -- VERY SLOW!
--JOIN #rootTempTable tt ON Location.RootID = tt.RootID -- Fast
--JOIN (SELECT 1360 as RootID) AS rt ON Location.RootID = rt.RootID -- Fast
--WHERE RootID = 1360 -- Fast
)
)
SELECT * FROM My_CTE WHERE (rownum > 0) AND (rownum <= 100) ORDER BY rownum
这是从使用 table 变量时开始的。查询运行时间超过 17 分钟:
XML 格式的执行计划
临时表:https://docs.google.com/open?id=0B66I-fxlyEtEZEthV3ZaWlNLWXM
表变量:https://docs.google.com/open?id=0B66I-fxlyEtEbUFZa3RJejFCTkk
【问题讨论】:
-
发布表变量和临时表版本的查询计划。
-
这实际上是我第一次在表变量中看到主键。我很好奇 - 执行计划有什么要说的?
-
我让表变量版本运行完成:17m 41s。您希望执行计划的任何特定格式?顺便说一句 - 主键只是我正在玩的东西,看看它是否会有所作为。好像没有。
-
请以 XML 格式发布执行计划。如果可能,作为文件共享的链接(例如 DropBox 或 google docs)。
-
不要忘记#temp 表版本。我们需要它们进行比较。
标签: sql-server common-table-expression table-variable