SQL Server查询行为

时间:2017-07-18 14:38:09

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

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-

对我而言,这似乎很荒谬,我不明白发生了什么,很难知道我的优化策略是否具有相关性,因为我不知道为什么我正在观察的看似非理性的行为是正当的......

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

CTE没有担保命令来运行这些陈述,我认为20个CTE太多了。您可以使用OPTION(FORCE ORDER)强制执行从上到下的执行。

为了选择几千行,不管复杂程度如何,任何超过1秒的行都是不可接受的。我会选择一个表函数的方法,所以我可以在内部创建哈希表或表变量,以完全控制每一步。这样,您就可以单独限制每个步骤中的优化程序范围。