計画を投稿したようです。引き分けの運だけ。
実際のクエリは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
良い計画と悪い計画の両方で、実行計画は「ステートメント最適化の早期終了の理由」を「タイムアウト」として示しています。
2つのプランの参加順序はわずかに異なります。
インデックスシークで満たされないプランへの唯一の参加は、での参加Tab9
です。これには63,926行あります。
実行プランに欠落しているインデックスの詳細は、次のインデックスを作成することを示唆しています。
CREATE NONCLUSTERED INDEX [miising_index]
ON [dbo].[Tab9] ([Date1],[Date2])
INCLUDE ([Tab13Id])
悪い計画の問題のある部分は、SQL SentryPlanExplorerではっきりと見ることができます。

SQL Serverは、の結合に入る前の結合から1.349174行が返されると見積もっていますTab9
。したがって、ネストされたループの結合には、内部テーブルでスキャンを1.349174回実行する必要があるかのようにコストがかかります。
実際、2,600行がその結合にフィードされます。つまり、 Tab9
(2,600 * 63,926 = 164,569,600行)の2,600回のフルスキャンが実行されます。
たまたま、良い計画では、結合に入る行の推定数は2.74319です。これはまだ3桁間違っていますが、見積もりがわずかに増加しているということは、SQLServerが代わりにハッシュ結合を優先することを意味します。ハッシュ結合は1回のパススルーを実行するだけですTab9

まず、不足しているインデックスをに追加してみますTab9
。
また/代わりに、関連するすべてのテーブル(特に、などの日付述語を持つテーブル)の統計を更新してTab2
Tab3
Tab7
Tab8
Tab6
、計画の左側にある推定行と実際の行の間の大きな不一致を修正する方法があるかどうかを確認してください。
また、クエリを小さな部分に分割し、これらを適切なインデックスを持つ一時テーブルに具体化すると役立つ場合があります。SQL Serverは、これらの部分的な結果の統計を使用して、計画の後半で結合をより適切に決定できます。
最後の手段としてのみ、クエリヒントを使用して、ハッシュ結合を使用してプランを強制することを検討します。それを行うためのオプションは、USE PLAN
すべての結合タイプと順序を含めて、必要なプランを正確に指示する場合のヒントか、を指定することによって選択できますLEFT OUTER HASH JOIN tab9 ...
。この2番目のオプションには、プラン内のすべての参加注文を修正するという副作用もあります。どちらも、SQL Serverが大幅に制限されることを意味します。これは、データ分散の変更に合わせて計画を調整する機能です。