2010-10-01 68 views
1

这很难解释,但我会尝试。 query plan pic复杂查询的CTE查询计划 - 同一个init查询的三重运行 - 为什么?

当你在连接query_plan图片中看到(这是查询计划“在同一个地方”查询如下所述),有3几乎相同的“块” - 我的问题是为什么呢?在我看来,当我有“全在一起”(见下文)查询“初始化”块(这是相当沉重的)是用不同的过滤器运行三次,而不是后来被SPOOLED和重复使用。

此查询执行时间约为45秒。 它查询可以在一个形式呈现:

-- Complex "All in One place" Query 
WITH init as (
    Init1 complex query here -- (10 sec to run) if executed alone 
) 
, step1 as (select * from init .. joins... where ... etc), 
step2 as (select *, row_number() over(__condition__) as rn from step1 where _filter1_) 
, step3 as (select * from step2 where __filter2_), 
.... some more steps could be here .... 
select * 
into target_table 
from step_N; 
-- 45sec CPU time 

这里最重要的是,我使用的第一步,第二步,...,内StepN表“和”条款顺序 - 第1步使用INIT表,所以Step2使用Step1表,Step3使用Step2 Table等。我需要这个,因为我在稍后用于过滤的每个步骤之后处理不同的排名。

如果变化这个复杂的CTE查询(我把初始化查询到表的结果,再处理其他步骤不改变):

-- Complex query separated from the rest of the query 
with Init as ( 
    The same Init1 complex query here 
) 
select * 
into test_init 
from init; 
-- 10sec CPU time 

with step1 as (select * from test_init .. joins... where ... etc), 
step2 as (select *, row_number() over(__condition__) as rn from step1 where _filter1_) , 
step3 as (select * from step2 where __filter2_), 
.... some more steps could be here .... 
select * 
into target_table 
from step_N; 
-- 5sec CPU time 

我的EXEC时间约15secs,这似乎是确定对我来说。因为10秒是第一个难以改进的复杂查询。

因此,我不能得到这个MS SQL Server 2005的行为?有人可以向我解释这个吗?我想,这很有趣!

回答

1

看起来像优化器认为它会更快地运行查询三次不同的条件。优化器并不总是正确的。

实际上,使用临时表来强制SQL Server首先执行整个复杂查询是很常见的。通常情况下,你会使用一个临时表,而不是test_init

insert into #temptbl select * from Init 

临时表也使用SQL Server来存储连接和子查询的结果。使用临时表格不会对性能产生负面影响。

+0

我们稍后使用表格有时用于质量保证目的。临时表在适当的地方使用。嗯......有没有办法“告诉”MS SQL,最好把结果放在假脱机和重用中?写一个计划,提示,什么? – zmische 2010-10-01 22:08:10

+0

@zmische - 对于计划提示可能是可行的,但记住,spool无论如何都只是tempdb中的工作表。 – 2010-10-01 22:23:29

+0

是的,你说得对。但是我要在一个查询中完成这项工作,而不需要额外的选择。如果从MS SQL服务器的角度来看,更是如此。 %)Thx无论如何! – zmische 2010-10-01 22:59:54