SQLクエリの最適化のための洞察力(任意の)要求
-
21-08-2019 - |
質問
I起因一緒に接合される情報の膨大な量に特にスロークエリを持っています。しかし、私は(テーブルからIDを選択)で、IDの形状にwhere句を追加する必要がありました。
私は以下からゲイン、およびより差し迫った、それも望ましい結果が得られますがあるかどうかを知りたい。
select a.* from a where a.id in (select id from b where b.id = a.id)
の代替として:
select a.* from a where a.id in (select id from b)
アップデート: MySQLの 申し訳ありません、より具体的にすることはできません 表Aは、効果的に7つの異なるテーブル間の結合です。 *の使用は例です。
編集、bが選択されません。
解決
あなたの質問はこれら二つの違いについてでした
select a.* from a where a.id in (select id from b where b.id = a.id)
select a.* from a where a.id in (select id from b)
前者は相関のサブクエリです。これは、MySQLはa
の行ごとにサブクエリを実行させてもよい。
後者は無相関のサブクエリです。 MySQLが一度実行しa
の各行との比較の結果をキャッシュすることができる必要があります。
私は後者を使用することになります。
他のヒント
あなたがリストの両方のクエリは同等です
select a.*
from a
inner join b on b.id = a.id
ほとんどすべてのオプティマイザは、同じ方法でそれらを実行します。
あなたは、実際の実行計画を投稿することができ、ここで誰かがあなたにそれをスピードアップする方法を与えるかもしれません。それはあなたが使用しているデータベースサーバーを指定した場合に役立ちます。
YMMV、私は頻繁に使用して発見したことはINは、クエリの実行速度になる代わりにEXISTSます。
SELECT a.* FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)
もちろん、クエリの残りの部分とコンテキストを見ることなく、これは、クエリがどの速くしないことがあります。
参加がより好ましい選択肢かもしれないが、a.idは一度Bのidカラム内で複数表示された場合、あなたはそこにDISTINCTをスローしなければならない、とあなたはより多くの可能性が高い最適化の面で逆方向に行きます。
私はこのようなサブクエリを使用することはありません。 Aに参加することははるかに高速になります。
select a.*
from a
join b on a.id = b.id
を選択し使用していません。もちろん、*のいずれか(特に、少なくとも一つのフィールドが繰り返される加入行っているときにそれを使用することはありません)、それはunnneededデータを送信するために、ネットワークリソースを浪費ます。
あなたが実行計画を見たことがありますか?
どの程度
select a.*
from a
inner join b
on a.id = b.id
おそらくIDフィールドが主キーですか?
Select a.* from a
inner join (Select distinct id from b) c
on a.ID = c.AssetID
私はすべての3つのバージョンを試してみましたが、彼らはほぼ同じ走りました。実行計画は、同じ(内部ジョイン、IN()とし、ここで、サブクエリで句なし存在)
ましたあなたはBから他のフィールドを選択していないので、私が使用することを好むどこIN(...選択)誰もがBでの場合にのみに表示(クエリを見て、あなたがやろうとしているものを知っているだろう。 )。
あなたの問題は、「A」内7つの表に最も可能性が高いです。
テーブルFROM「a.id」を含有させます 次回は参加します:インナーはa.id = b.id
にBに参加その後、他の6つのテーブルに参加します。
あなたは本当にあなたが本当の助けをしたい場合は、各テーブルのすべてのインデックス、およびおおよその行数をリストし、クエリ全体を表示する必要があります。