2017-07-14 10 views
0

私は私に同じ結果を与える2人のSQLの持っている:サブクエリ対結合とどこが速いのですか?

クエリ1:

SELECT 
u.*, COUNT(po.order_id) products_count 
FROM (SELECT * FROM orders o WHERE o.date >= (CURRENT_DATE() - INTERVAL 1 MONTH)) o 
LEFT JOIN products_orders po ON po.order_id=o.id 
JOIN users u ON u.id=o.user_id 
GROUP BY po.order_id 

とクエリ2:

SELECT 
u.*, o.id order_id, COUNT(po.order_id) products_count 
FROM users u 
JOIN orders o ON o.user_id=u.id 
LEFT JOIN products_orders po ON po.order_id=o.id 
WHERE o.date >= (CURRENT_DATE() - INTERVAL 1 MONTH) 
GROUP BY po.order_id 

を、私は1つが速くなるべき...だろうか? クエリの説明では、それらが等しいと表示されます...あなたはどう思いますか?必要がないので、 Query 1 Query 2

+0

説明プランが同じ場合、パフォーマンスは同じにする必要があります。留意してくださいコストベースのオプティマイザは、SQLで "フィドル"して、可能な限り最良の結果を得ることができます(少なくとも正確性とパフォーマンスの点で最も良いと思うもの) – xQbert

+0

クロスポストしないでください:https:// dba .stackexchange.com/questions/179878/subquery-vs-join-and-where-which-one-is-faster –

+0

投票のために投票されました – breq

答えて

0

クエリはあなたが別の列を選択まったく同じではありません
あなたは...
が副選択withou速くクエリする場所を避け句の上に直接にWHERE条件を追加することができます店舗サブクエリ

SELECT 
     u.* 
     , o.id order_id 
     , COUNT(po.order_id) products_count 
    FROM users u 
    INNER JOIN orders o ON o.user_id=u.id 
      and o.date >= (CURRENT_DATE() - INTERVAL 1 MONTH) 
    LEFT JOIN products_orders po ON po.order_id=o.id 
    GROUP BY po.order_id 

チェックを回避し、

0

通常Jで使用しての結果のための一時テーブルOINはサブクエリより効率的で、EXPLAIN出力に反映されます。これは、サブクエリを使用すると、オンザフライで仮想テーブルを作成し、そのテーブルでクエリする必要があるためです。既存のテーブルでJOINを使用すると、このステップはスキップされ、オプティマイザはこのテーブルの知識をインデックスまたはキャッシュデータの形で利用できます。

あなたのEXPLAINがここで等しい理由は、サブクエリがどれほどシンプルなのかが原因です。 whereを条件とするselect allを実行するだけなので、オプティマイザは通常このことに気付き、テーブルのサブクエリとJOINを解析し、後でWHEREを適用します。したがって、オプティマイザは、サブクエリ・バージョンをJOINバージョンとして、実行する前に効果的に書き換えます。

関連する問題