SQL Server 2008 R2查询优化器难题
我们有两个表,每个表都包含900万行。70.000行不同,其他相同。
快13秒
select * from bigtable1
except select * from similar_bigtable2
这样可以对输出进行排序,而且速度也很快(13秒),
select * into #q from bigtable1
except select * from similar_bigtable2
select * from #q order by sort_column
尽管这非常慢:
;with q as (
select * from bigtable1
except select * from similar_bigtable2
)
select * from q order by sort_column
甚至是我有时用来提示SQL Server的“技巧”,它都需要在继续进行之前预先计算查询的某个部分,它不起作用,并且也会导致查询速度变慢:
;with q as (
select top 100 percent * from bigtable1
except select * from similar_bigtable2
)
select * from q order by sort_column
查看查询计划的原因并不难发现:
SQL Server 在哈希匹配之前放置两种900万行,而我希望它在哈希匹配之后仅添加一种70.000行。
那么问题来了:我如何指示查询优化器执行此操作?
3
它不会在哈希匹配之前进行排序,而是先进行排序然后进行合并联接(而不是哈希联接)。也许有一个提示可以强制执行哈希联接(或阻止合并联接)?
—
Thilo 2012年
似乎SQL Server查询优化器确定对数据进行排序是有好处的,因此它可以使用快得多的合并联接(仅适用于排序的数据),而不是慢得多的哈希匹配联接或嵌套循环联接....
—
marc_s
您是否尝试过替代
—
亚伦·伯特兰
EXCEPT
(例如OUTER JOIN
)的方法?我意识到语法不太方便,但是您可以在那里更好地使用索引/联接提示(或者您可能不需要)。您现在正在使用的替代方法(首先填充到#temp表中)是最后的解决方法,但在某些情况下,这是强制优化器以所需方式将查询的两个部分完全分开的唯一方法。