2013-02-19 15 views
5

私は遅いクエリですか?それは改善することができますか?

世界(名前、大陸、地域、人口、GDP)

SELECT w1.name, w1.continent, w1.population 
FROM world w1 
WHERE 25000000 >= ALL(SELECT w2.population FROM world w2 WHERE w2.continent=w1.continent) 
SQLZOO " SELECT within SELECT tutorial" を通過し、ここで仕事をしたクエリの一つだ(タスクしました)

私の質問はそのようなクエリの有効性に関するものです。サブクエリは、メインクエリの各行(国)に対して実行され、したがって、指定された大陸のALLリストを繰り返し再作成します。

  1. Oracleの最適化が何らかの方法で処理されるのではないでしょうか。
  2. 相関サブクエリなしで再プログラムすることはできますか?
+0

は、ここでデータ/クエリのフィドルです:http://sqlfiddle.com/#!4/2aed1/1 – Wilduck

答えて

1

あなたはcorrealtedサブクエリなしで問合せをリライトしたい場合は、ここでは一つの方法である:

SELECT w1.name, w1.continent, w1.population 
FROM world w1 
    JOIN 
    (SELECT continent, MAX(population) AS max_population 
     FROM world 
     GROUP BY continent 
    ) c 
    ON c.continent = w1.continent 
WHERE 25000000 >= c.max_population ; 

私はこれがより速くなることを意味するものではありません。オラクルのオプティマイザはかなり良いですが、これは単純な全体的なクエリですが、あなたはそれを記述します。ここでは別の簡素化です:

SELECT w1.name, w1.continent, w1.population 
FROM world w1 
    JOIN 
    (SELECT continent 
     FROM world 
     GROUP BY continent 
     HAVING MAX(population) <= 25000000 
    ) c 
    ON c.continent = w1.continent ; 
+0

私はあなたのソリューション(特に2番目のソリューション)が好きです。 私はこれを私が探していたものと信じています。 –

3

まず、oracleが評価するためにこの問合せをどのように変換するかを理解する必要があります。

SELECT w1.name 
    , w1.continent 
    , w1.population 
FROM world w1 
WHERE 25000000 >= ALL(SELECT w2.population 
         FROM world w2 
         WHERE w2.continent=w1.continent 
        ); 

次に、オプティマイザは、その後さらに変換をオプティマイザを任意の比較演算子および相補比較演算子

SELECT w1.name 
     , w1.continent 
     , w1.population 
    FROM world w1 
    WHERE NOT(25000000 < ANY (SELECT w2.population 
         FROM world w2 
         WHERE w2.continent=w1.continent) 
     ); 

を使用して同等の条件にサブクエリが続くすべての比較演算子を使用する条件を変換します2番目のクエリは、ANY比較演算子で条件を変換するためのルールを使用し、その後に相関サブクエリが続きます。

SELECT w1.name 
     , w1.continent 
     , w1.population 
    FROM world w1 
    WHERE 
    NOT EXISTS (SELECT w2.population 
        FROM world w2 
       WHERE w2.continent=w1.continent 
        AND 25000000 < w2.population 
       ); 

これは、私はあなたの質問についてはOracleソースLink

から取られています

  1. はいオラクルは、このの世話をする、変換が示唆として、Oracleはより良いquery.But上記の変換を理解する方法をどのようにこのエンド結果クエリの作業。
  2. はい、これは相関サブクエリなしでも実行できますが、同じ大陸を持つテーブル内の他のレコードを比較する必要があるため、同じテーブルに結合する必要があります。私が間違っていれば私を修正してください]
+0

私は考えていた(しかし、見つけることができませんでした) "を構築するソリューションは、各大陸を**一度だけ評価することによって、基準に合致するすべての大陸の「静的な」リストを得ることができる。 –

1

あなたは二回表をスキャンする必要なく、これを簡略化することができます。

select a.name, a.continent, a.population, a.max_pop 
    from (select w1.name, w1.continent, w1.population, 
       max(w1.population) over (partition by w1.continent) max_pop 
      from world w1 
     ) a 
where 25000000 >= a.max_pop; 
関連する問題