【问题标题】:SQL Server query behaviorSQL Server 查询行为
【发布时间】:2017-07-18 14:38:09
【问题描述】:

vw_project 是一个包含 20 个 CTE 的视图,多次加入它们并返回 56 列

其中许多 CTE 是自联接(经典的“每组最后一行”,在我们的例子中,我们得到每个项目的最后一个相关对象产品/客户/经理)

涉及的大多数表(可能是 40 个?)不超过 1000 行,视图本身返回 634 行。

我们正在努力改善这个视图的非常糟糕的表现。 我们进行了非规范化(从 TPT 变为 TPH),并将连接数量减少了一半,几乎没有影响。

但我不明白我得到的以下结果:

select * from  vw_Project (TPT)
2 sec 

select * from  vw_Project (TPH)
2 sec 

select Id from vw_Project (TPH , TPT is instant)
6 sec

select 1 from vw_Project  (TPH , TPT is instant)
6 sec

select count(1) from vw_Project (TPH , TPT is instant)
6 sec

最后一个(6秒)的执行计划: https://www.brentozar.com/pastetheplan/?id=r1DqRciBW

sp_updatestats 之后的执行计划 https://www.brentozar.com/pastetheplan/?id=H1Cuwsor-

对我来说,这似乎很荒谬,我不明白发生了什么,也很难知道我的优化策略是否相关,因为我不知道是什么证明了我观察到的明显不合理的行为......

有什么线索吗?

【问题讨论】:

  • 您有执行计划可以与我们分享吗?
  • 您可以尝试粘贴其中一个选择的计划(例如 6 秒的)here 供大家查看。
  • 什么是TPT和TPH?
  • 你能用选项(重新编译)尝试相同的查询吗?结果是什么?估计通常看起来非常非常偏斜。像 dbo.Circuit_Journal_Etape 估计是 1.6 行,实际行是 252K(?!),当然,当扫描可能会更好时,会有一个搜索。
  • @Proviste 您在测试环境中吗?如果是这样,您可以尝试手动 update statistics 看看是否能解决您的问题。

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


【解决方案1】:

CTE 没有保证运行语句的顺序,我认为 20 个 CTE 太多了。您可以使用 OPTION (FORCE ORDER) 从上到下强制执行。

对于选择几千行,无论复杂程度如何,超过 1 秒的任何内容都是不可接受的。我会选择一种表函数的方法,这样我就可以在里面创建哈希表或表变量来完全控制每个步骤。这样您就可以将优化器范围限制在每​​个步骤中。

【讨论】:

  • OPTION (FORCE ORDER) litteraly 反转结果(6s 变为 2s,2s 变为 6s)
  • 有趣。 FORCE ORDER 不会单独工作 - 需要有一个 CTE 的逻辑顺序,例如 WITH A 、 B、 C ......其中 B 使用 A 而 C 使用 B 等等。如果顶级 CTE 可以很好地过滤数据,那么较低的 CTE 会在使用更少的数据时做得更好。所以尝试改变顺序 - 将好的过滤器 CTE 尽可能放在首位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
相关资源
最近更新 更多