2012-07-25 63 views
1

我有一个视图,为我的项目汇总了很多信息。我们称之为v_item_details。子查询X临时表X动态SQL X表值函数

这个视图是通过递归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连接查询提示可以工作,但它没有,因为虽然它的确从子查询开始进行循环,但查看的查询计划与快速查询不同,所以我仍然有性能问题。

最好的问候, 卡洛斯·乔丹

回答

0

这将是有帮助的,我们可以建立我们自己的SQL Server实例再现和诊断问题一个活生生的例子。如果没有这一点,这里有一些事情,我可能会尝试:

  • 确保将items表的统计信息是最新
  • 尝试使用JOIN,而不是IN子句(我知道这些应通常是相同的,但在某些情况下它们的行为会非常不同,例如COLUMNSTORE索引,所以也可能存在具有递归CTE的怪癖)
  • 确保vw_item_details中使用的表具有正确的主键, /或索引
  • 尝试仅选择需要的列而不是*从vw_item_details(a lo ng-shot,但你永远不知道......)