子查询X临时表X动态sql X表值函数

时间:2012-07-25 14:11:39

标签: sql-server performance subquery dynamic-sql table-variable

我有一个观点,总结了我的项目的很多信息。我们称之为v_item_details。

此视图是通过递归cte定义的,如果未应用正确的过滤,则会变得非常慢。基本上,如果我提供项目ID的列表,事情就会顺利进行。所以SELECT * FROM v_item_details WHERE item_id IN(1,2,3)之类的东西会在1秒内运行。

当我尝试获取另一个表中定义的一组项目的项目详细信息时,事情变得复杂。查询SELECT * FROM v_item_details WHERE item_id IN (SELECT item_id FROM items WHERE group_id = 1)将花费1分钟以上,即使group_id已编制索引且子查询返回与先前查询(1,2和3)相同的item_id。

我尝试创建一个表变量并在其中插入子查询的结果,然后对其进行连接,但它仍然需要1分钟。

接下来我尝试用一​​个表值函数来包装我的视图,该函数接收item_id作为参数,然后进行交叉应用,尝试强制执行与简单选择相同的计划,但这需要4分钟!

现在我正在使用选择id的动态查询,然后执行快速子查询。但这不是最理想的,因为现在我遇到了存储过程,而不是我可以进一步操作的视图。

有关如何强制SQL首先选择子查询中的值然后运行快速子查询的任何想法?我认为使用LOOP连接查询提示会起作用,但事实并非如此,因为尽管它确实从子查询开始执行循环,但视图的查询计划与快速查询不同,所以我仍然有表现问题。

祝你好运, Carlos Jourdan

1 个答案:

答案 0 :(得分:0)

有一个可以在我们自己的SQL Server实例上构建的实例来重现和诊断问题会很有帮助。如果没有,我可以尝试以下几点:

  • 确保items表上的统计信息是最新的
  • 尝试使用JOIN而不是IN子句(我知道这些通常应该是相同的,但在某些情况下它们的行为会有很大不同,例如使用COLUMNSTORE索引,所以也许还有带递归CTE的怪癖)
  • 确保vw_item_details中使用的表具有正确的主键和/或索引
  • 尝试仅选择您需要的列而不是* vw_item_details(远射,但您永远不知道......)