Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.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 server 使用表变量时,公用表表达式速度较慢_Sql Server_Common Table Expression_Table Variable - Fatal编程技术网

Sql server 使用表变量时,公用表表达式速度较慢

Sql server 使用表变量时,公用表表达式速度较慢,sql-server,common-table-expression,table-variable,Sql Server,Common Table Expression,Table Variable,我一直在试验以下简化的CTE。使用表变量时,查询会运行几分钟,然后我取消它。任何其他被注释掉的方法都会在不到一秒钟内返回 如果我用一个内部连接替换整个WHERE子句,它也很快 你知道为什么使用表变量会运行得这么慢吗 FWIW:数据库包含250万条记录,内部查询返回2条记录 创建表rootTestable RootID int主键 插入roottentable值1360; 声明@rootTableVar表RootID int主键; 插入@rootTableVar值1360; 以我的名义 选择按d.

我一直在试验以下简化的CTE。使用表变量时,查询会运行几分钟,然后我取消它。任何其他被注释掉的方法都会在不到一秒钟内返回

如果我用一个内部连接替换整个WHERE子句,它也很快

你知道为什么使用表变量会运行得这么慢吗

FWIW:数据库包含250万条记录,内部查询返回2条记录

创建表rootTestable RootID int主键 插入roottentable值1360; 声明@rootTableVar表RootID int主键; 插入@rootTableVar值1360; 以我的名义 选择按d.DocumentID、d.DocumentID、d.Title排序的行号 来自[文件]d d.LocationID在哪里 选择LocationID 从地点 在Location.RootID=rtv.RootID上加入@rootTableVar rtv-非常慢! -在Location.RootID=tt.RootID-Fast上加入rootTestable tt -在Location.RootID=rt.RootID-Fast上加入选择1360作为RootID作为rt -其中RootID=1360-Fast
从My_CTE中选择*,其中rownum>0和rownum查询计划明确表明,表变量版本存在臭名昭著的表变量基数估计问题。这主要是因为,与临时表不同,表变量不支持统计信息。保罗·怀特(Paul White)的这篇文章详细解释了这一点:

这也清楚地表明,最简单的解决方案可能是添加一个选项重新编译;子句添加到查询的末尾。尽管这在早期版本的SQL Server中可能不起作用,但在以后的版本中,它应该会使SQL Server获得更好的基数估计,从而生成与临时表版本相同的查询计划


如果这不起作用,请告诉我,因为还有其他一些不太理想的可能解决方案。

部分解决方案:帮助很大的是按照SQL Server的建议,使用索引物理统计报告重建或重新组织表上的索引。右键单击数据库>报告>标准报告>索引物理统计即可获得此报告。

发布表变量和临时表版本的查询计划。这实际上是我第一次在表变量中看到主键。我很好奇-执行计划要说什么?我让表变量版本运行到完成:17m 41s。您希望执行计划采用什么特殊格式?顺便说一句,主键只是我一直在玩的东西,看看它是否会有所不同。似乎没有。请用XML发布执行计划。如果可能,作为文件共享的链接,例如DropBox或google docs。不要忘记临时表的版本。我们需要它们来比较。谢谢-一个很好的建议。然而,我似乎只能补充说,在外部选择后,而不是在CTE内,这似乎没有多大区别。最后,我重建/重新组织了索引,这在某种程度上有所帮助,我还研究了不使用CTE的其他查询。