我看你現在已經發布the plans。只是運氣的平局。
您的實際查詢是16表連接。
SELECT max(atDate1) AS AtDate1,
min(atDate2) AS AtDate2,
max(vtDate1) AS vtDate1,
min(vtDate2) AS vtDate2,
max(bgtDate1) AS bgtDate1,
min(bgtDate2) AS bgtDate2,
max(lftDate1) AS lftDate1,
min(lftDate2) AS lftDate2,
max(lgtDate1) AS lgtDate1,
min(lgtDate2) AS lgtDate2,
max(bltDate1) AS bltDate1,
min(bltDate2) AS bltDate2
FROM (SELECT TOP 100000 at.Date1 AS atDate1,
at.Date2 AS atDate2,
vt.Date1 AS vtDate1,
vt.Date2 AS vtDate2,
bgt.Date1 AS bgtDate1,
bgt.Date2 AS bgtDate2,
lft.Date1 AS lftDate1,
lft.Date2 AS lftDate2,
lgt.Date1 AS lgtDate1,
lgt.Date2 AS lgtDate2,
blt.Date1 AS bltDate1,
blt.Date2 AS bltDate2
FROM dbo.Tab1 a
INNER JOIN dbo.Tab2 at
ON a.id = at.Tab1Id
AND cast(Getdate() AS DATE) BETWEEN at.Date1 AND at.Date2
INNER JOIN dbo.Tab5 v
ON v.Tab1Id = a.Id
INNER JOIN dbo.Tab16 g
ON g.Tab5Id = v.Id
INNER JOIN dbo.Tab3 vt
ON v.id = vt.Tab5Id
AND cast(Getdate() AS DATE) BETWEEN vt.Date1 AND vt.Date2
LEFT OUTER JOIN dbo.Tab4 vk
ON v.id = vk.Tab5Id
LEFT OUTER JOIN dbo.VerkaufsTab3 vkt
ON vk.id = vkt.Tab4Id
LEFT OUTER JOIN dbo.Plu p
ON p.Tab4Id = vk.Id
LEFT OUTER JOIN dbo.Tab15 bg
ON bg.Tab5Id = v.Id
LEFT OUTER JOIN dbo.Tab7 bgt
ON bgt.Tab15Id = bg.Id
AND cast(Getdate() AS DATE) BETWEEN bgt.Date1 AND bgt.Date2
LEFT OUTER JOIN dbo.Tab11 b
ON b.Tab15Id = bg.Id
LEFT OUTER JOIN dbo.Tab14 lf
ON lf.Id = b.Id
LEFT OUTER JOIN dbo.Tab8 lft
ON lft.Tab14Id = lf.Id
AND cast(Getdate() AS DATE) BETWEEN lft.Date1 AND lft.Date2
LEFT OUTER JOIN dbo.Tab13 lg
ON lg.Id = b.Id
LEFT OUTER JOIN dbo.Tab9 lgt
ON lgt.Tab13Id = lg.Id
AND cast(Getdate() AS DATE) BETWEEN lgt.Date1 AND lgt.Date2
LEFT OUTER JOIN dbo.Tab10 bl
ON bl.Tab11Id = b.Id
LEFT OUTER JOIN dbo.Tab6 blt
ON blt.Tab10Id = bl.Id
AND cast(Getdate() AS DATE) BETWEEN blt.Date1 AND blt.Date2
WHERE a.Nummer = 223889) B
在這兩個好和壞計劃執行計劃顯示爲「超時」,「爲語句優化的提前終止原因」。
這兩個計劃有不同的連接順序。
索引查找不滿足的計劃中的唯一連接是Tab9
。這有63,926行。
執行計劃中缺少的索引詳細信息建議您創建以下索引。
CREATE NONCLUSTERED INDEX [miising_index]
ON [dbo].[Tab9] ([Date1],[Date2])
INCLUDE ([Tab13Id])
壞計劃的問題的一部分,可以清楚地看到在SQL哨兵方案資源管理器
SQL Server的估計,從以前的連接進入的連接上1.349174行將返回Tab9
。因此嵌套循環連接的代價就好像它需要在內表上執行1.349174次掃描一樣。
事實上,2,600行進入該連接,這意味着它執行2,600次全掃描Tab9
(2,600 * 63,926 = 164,569,600行。)
恰好如此,在良好的計劃中,進入連接的估計行數爲2.74319。這仍然錯誤三個數量級,但稍微增加的估計意味着SQL Server支持散列連接。哈希連接少了點一次通過Tab9
我第一次嘗試在Tab9
加入缺失指數。
此外/相反,你可以嘗試更新所涉及的所有表的統計數據(尤其是那些有日期謂詞如Tab2
Tab3
Tab7
Tab8
Tab6
),看看是否能在某種程度上對糾正估計與實際行之間的巨大差異計劃的左邊。
同樣將查詢分解爲更小的部分並將這些查詢轉化爲具有適當索引的臨時表可能會有所幫助。 SQL Server然後可以使用這些部分結果的統計信息來爲計劃中稍後的連接做出更好的決策。
只有作爲最後的手段,我會考慮使用查詢提示嘗試強制使用散列連接的計劃。您的選擇可以是USE PLAN
提示,在這種情況下,您可以完全確定所需的計劃,包括所有加入類型和訂單,或者通過陳述LEFT OUTER HASH JOIN tab9 ...
。第二個選項也具有修復計劃中所有連接訂單的副作用。兩者都意味着SQL Server將受到嚴重限制,因爲它能夠根據數據分佈的變化調整計劃。
您必須查看執行計劃才能確定。它有可能是在採用TOP比沒有采用更有效的路徑。 – Khan 2013-03-15 14:45:53
這可能是由優化器問題引起的。你能否提供兩種查詢的執行計劃? – 2013-03-15 14:46:53
提供執行計劃的最佳方式是在SSMS中運行它們,並啓用「查詢 - >包括實際執行計劃」選項,然後將XML版本上傳到像pastebin這樣的站點。請參閱[如何向某人提供執行計劃以供分析?](http://meta.dba.stackexchange.com/questions/796/how-do-i-provide-an-execution-plan-to-someone-爲分析)更多。 – 2013-03-15 15:06:51