これはスキーマです:
そして、これは私が理解しているように、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 はプログラミング スキルをテストする準備ができています!)。