【问题标题】:Same unit of operation takes different length of time in two pretty similar queries相同的操作单元在两个非常相似的查询中花费不同的时间
【发布时间】:2015-08-02 15:26:27
【问题描述】:

我有这两个问题:

SELECT *
FROM ActionMessage am 
JOIN vTasks vt ON am.TasksSeq = vt.TasksSeq
JOIN Tasks t2 ON t2.TasksSeq = vt.UltimateParent
WHERE vt.UltimateParent = 1225 

SELECT *
FROM ActionMessage am 
JOIN vTasks vt ON am.TasksSeq = vt.TasksSeq
JOIN Tasks t2 ON t2.TasksSeq = vt.UltimateParent
WHERE t2.TasksSeq = 1225 -- NOTE: this is the difference between 

vTasks 是一个视图,使用左自连接可以达到 4 级,计算给定任务的最顶层父级。
当我运行查询时,第一个查询需要不到一秒,但第二个查询需要 15 秒。
然后我查看了他们的实际执行计划,如果需要,我附上了图片链接。

如果你看一下图片,它们都有一个索引查找操作。
根据第一个计划,它需要整个查询执行时间的 30%。
第一个计划属于执行时间较长的查询。
所以我可以得出结论,查询 1 的索引查找需要 5 秒。
我们在计划 2 中进行了相同的操作,但运行时间显然不到一秒。
我在两个计划中查看了此操作的详细信息,但统计数据和信息看起来相同。

我的问题是,因为这两个查询几乎相同,我至少希望两者中的索引搜索会执行相同的操作。那么为什么它们的执行时间会如此不同呢?

以下是计划 2 的更广泛视图:

【问题讨论】:

  • vt 与 t2 相比有多少行满足相应条件?此外,您可能想更新统计信息msdn.microsoft.com/en-us/library/ms187348.aspx 表格定义也会有所帮助\
  • 查看vTasks 代码可能很有用。
  • 成本百分比和时间并不总是直接相关的。我猜想第一个计划(聚集索引扫描)上的这个粗体箭头需要大部分时间。
  • 第二张图不是第二次查询的完整计划吧?很难相信这些计划相差如此之大。
  • @AndriyM,他们都不是计划的第一个节点。

标签: sql-server query-performance sql-execution-plan


【解决方案1】:

在您的第一个查询中,您有一个 JOIN,它告诉 DBMS 对 Tasks 表的索引实体执行 聚集索引扫描,该表将与检查相关部分合并到 @ 987654324@ 表在WHERE 语句中由t2 别名,因此您将只有一个Clustered Index Scan

但是,当您在第二个查询中尝试检查视图时,DBMS 将再次将您的视图使用的 Tasks 数据加载到新的内存位置并执行另一次聚集索引扫描 em> 在新加载的数据上。


我建议您通过添加Index seek (Non-Clustered) 来优化ActionMessage 表,以便在您的查询中产生更多效果。

【讨论】:

  • 谢谢,但是这会影响在 am 表上的非聚集索引搜索吗?这部分消耗了大部分查询时间。
  • @Sahand Clustered Index Scan 表结构的原因,您可以使用ActionMessage 检查Tasks CREATE 语句,这不是最耗时的消费者,最耗时的是不相关的直接到你的计划;)。
  • 我想我可能会错过你的观点。 Actionmessage 已经有一个关于 taskseq 的索引,并且它正在计划中的 indexseek 中使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多