3

これはスキーマです:

ここに画像の説明を入力

そして、これは私が理解しているように、SQLオプティマイザーには複雑すぎるSQLです。

SELECT * FROM 
(
    select pp.Id as PaymentPartId,  b.Id as BudgetId, grouping(bp.ID) as g1 , sum(pp.Amount) PaymentsSum, sum(bp.Amount) BudgetSum
    from  Projects pr 
            inner join Payments p      ON pr.Id = p.ProjectID
            inner join PaymentParts pp ON p.Id = pp.PaymentId
            inner join Budgets b       ON pr.Id = b.ProjectID
            inner join Budgetparts bp  ON b.Id = bp.BudgetId
    group by pp.Id, b.Id, rollup(bp.ID)
)  x
WHERE   x.PaymentPartId = 777 

SQLFIDDLE: http://sqlfiddle.com/#!6/aa74e/11 (自動生成データ付き)

私が期待すること:実行計画には、 x.PaymentPartId のインデックス シークが含まれている必要があります。なんで?このクエリは次と同等であるためです。

select pp.Id as PaymentPartId,  b.Id as BudgetId,  grouping(bp.ID) as g1, sum(pp.Amount) PaymentsSum, sum(bp.Amount)  BudgetSum
from  Projects pr 
        inner join Payments p      ON pr.Id = p.ProjectID
        inner join PaymentParts pp ON p.Id = pp.PaymentId
        inner join Budgets b       ON pr.Id = b.ProjectID
        inner join Budgetparts bp  ON b.Id = bp.BudgetId
WHERE   pp.Id = 777
group by pp.Id, b.Id, rollup(bp.ID)

...そして最後のクエリはインデックス シークを使用します。

しかし、SQL Optimizer はインデックスの使用を拒否するだけでなく、すべてのヒントを無視します (sqlfiddle で期限切れにすることをお勧めします。これは非常に興味深いことです)。

そこで問題は、SQL Server Optimizer に強制的にインデックス シークを使用させることは不可能だというのは正しいでしょうか? ロールアップは、SQLオプティマイザーの「最適化フレーム」を2つの部分に分割するものであり、クエリ全体を最適化することを不可能にしているようです。

PSこの「プログラミング以外の質問」を締めくくることに投票した人は、オプティマイザのヒントを入力してみてください (sqlfiddle はプログラミング スキルをテストする準備ができています!)。

4

1 に答える 1

1

ヒントが機能しないのはなぜですか? - ロマン・ポクロフスキー

ドキュメントにあります: http://technet.microsoft.com/en-us/library/ms181714.aspx

クエリ ヒントは、サブクエリではなく、最上位クエリでのみ指定できます。

于 2014-03-07T15:05:21.273 に答える