Tsa*_*tra 1 join sql-server temporary-tables
我正在处理一个基本上将大量表聚合在一起的查询。
我尝试的第一种方法是将所有表内部连接成一个漂亮的大查询,看起来像这样:
select
a.col1
, a.col2
, a.col3
...
, b.col1
...
...
, l.col1
, l.col2
from myprimarytable a
join secondtable b on a.key = b.key
join third table c on a.key = c.key
...
join thelasttable l on a.key = b.key
Run Code Online (Sandbox Code Playgroud)
这需要永远运行。但是,看起来像这样的第二个解决方案:
create table #output (
primkey char(40)
, mycol1 char(1) null
, mycol2 decimal(20,1) null
...
, mylastcol varchar(max) null
)
insert into #output
select
a.col1
, a.col2
...
from myprimarytable a
update #output set
mycol3 = b.col1
, mycol4 = b.col2
...
from #output a
join secondtable b on a.primkey = b.key
...
Run Code Online (Sandbox Code Playgroud)
为什么带有更新的临时表比一次性完成所有连接的临时表花费的时间少得多(在我的特定情况下大约快 30 倍)?
考虑到涉及大量连接的中等复杂查询,SQL Server 具有创建高效查询计划的上限 - 没有 单一的确定查询何时复杂到足以导致问题的上限或魔术公式;它是逐案处理的,涉及从一些已知的期望中建立基线(人们有时认为某个查询不应该花费 30 秒,但有时这确实是该上下文的最佳和最佳结果)。在其他情况下,SQL Server 只是不堪重负,无法(至少在没有无限时间的情况下)快速提出最佳计划。所以它会花一些时间想出一个“我在这段时间能找到的最佳计划”,然后它会显示“提前终止的原因:超时”,你就会得到你所得到的。您可以强制 SQL Server 花更多时间使用跟踪标志 2301(Paul White 提到并链接到此答案中),但更多的时间可能不会有多大帮助(而且更多的编译时间对于最终用户的整体性能来说可能不是一件好事)。另一种选择是分解逻辑,以便 SQL Server 可以专注于优化较小的、不太复杂的查询。
把它想象成吃一个馅饼——你可能可以一次吃掉一个相当大的一块,但如果你的目标是吃掉整个馅饼,你可能想把它分散在多个环境中。
对于 SQL Server,在某些情况下,将逻辑块分开可以做得更好。这并不意味着您应该将所有联接简化为#temp
表瀑布,但在某些极端情况下,这是一种有效的解决方法。
归档时间: |
|
查看次数: |
7112 次 |
最近记录: |