SQL 結合表記を使用して開始できます。
SELECT DISTINCT P.HName, P.Age
FROM Hills AS H
JOIN Runs AS R ON H.MId = R.MId
JOIN Runners AS P ON P.HId = R.HId
WHERE H.Height > 1200
次に、WHERE 条件が Hills にのみ適用されることを確認できるため、検索条件を下げることができます。
SELECT DISTINCT P.HName, P.Age
FROM (SELECT MId FROM Hills WHERE Height > 1200) AS H
JOIN Runs AS R ON H.MId = R.MId
JOIN Runners AS P ON P.HId = R.HId
これは標準の最適化であり、SQL オプティマイザが自動的に実行します。実際、オプティマイザーが処理できるため、最初に表示されたクエリを大幅に書き換える価値はおそらくありません。私が考えている他の最適化は、DISTINCT 操作をレベルを下げることです。
SELECT P.HName, P.Age
FROM (SELECT DISTINCT R.HId
FROM (SELECT MId FROM Hills WHERE Height > 1200) AS H
JOIN Runs AS R ON H.MId = R.MId
) AS R1
JOIN Runners AS P ON P.HId = R1.HId
これにより、中間結果セットが可能な限り小さく保たれます。R1 には、1200 メートル (または 1200 フィートですか?) の丘を少なくとも 1 つ走った人の ID 値のリストが含まれており、詳細と 1:1 で結合できます。ランナーズテーブルで。オプティマイザーが DISTINCT 自体のプッシュダウンを推測できるかどうかを確認することは興味深いでしょう。
もちろん、関係代数では、DISTINCT 演算は「自動的に」行われます。すべての結果と中間結果は、常に重複のない関係です。
元の「関係代数」表記を考えると、次のようになります。
- π Name, Age(σ Height > 1200 (Hills × Runners × Runs))
これは、上記の最初の SQL ステートメントに対応します。
次に、2 番目の SQL ステートメントは (多かれ少なかれ) 以下に対応します。
- π 名前、年齢 ((π MId (σ Height > 1200 (Hills))) × Runners × Runs)
次に、3 番目の SQL ステートメントは (多かれ少なかれ) 以下に対応します。
- π Name, Age ((π HId ((π MId (σ Height > 1200 (Hills))) × Runs)) × Runners)
ここで、括弧が関係代数に式を順番に評価させると仮定しています。可能な限り最小限の数の括弧が含まれているかどうかはわかりませんが、そこにある括弧にはあいまいさの余地があまりありません。