1

我的观点总结了我的物品的很多信息。我们称之为 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)即使 group_id 已编入索引并且子查询返回与先前查询(1,2 和 3)相同的 item_id,该查询仍将花费 1 分钟。

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

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

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

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

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

4

1 回答 1

0

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

  • 确保items表上的统计信息是最新的
  • 尝试使用 JOIN 而不是 IN 子句(我知道这些通常应该是相同的,但在某些情况下它们的行为非常不同,例如使用 COLUMNSTORE 索引,所以递归 CTE 也可能存在怪癖)
  • 确保使用的表vw_item_details具有正确的主键和/或索引
  • 尝试仅选择您需要的列,而不是 * from vw_item_details(一个长镜头,但你永远不知道......)
于 2012-08-09T08:25:33.553 回答