2011-12-21 19 views
3

SELECTSELECT内で使用してクエリの数を減らすのが一般的です。しかし、これを調べると、クエリが遅くなる(これはMySQLのパフォーマンスにとって明らかに有害である)。 「; 0.000090s程度の時間をロックし、約200行を調べてクエリ時間3-4s」私はこれがのクエリを遅らせるにつながるmysqlクエリでSELECT内でSELECTを使用する

SELECT something 
FROM posts 
WHERE id IN (
    SELECT tag_map.id 
    FROM tag_map 
    INNER JOIN tags 
    ON tags.tag_id=tag_map.tag_id 
    WHERE tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6') 
) 

ような単純なクエリを持っていました。

SELECTクエリを分割すると、それぞれが非常に高速になります。しかし、これにより高い並行性が得られないクエリの数が増えます。

通常の状況ですか、それとも何か問題がありますか?

+2

SELECT' ''内SELECT'を!これはその映画のようなものです... Inselection。 –

答えて

12

を置き換えることができますので、また、あなたがタグ列を持ったテーブルで状態は、このような副問合せを行うと、「相関クエリ」です。つまり、外部SELECTの結果は内部SELECTの結果に依存します。結果は、内部クエリが行ごとに1回実行されることです。これは非常に遅いです。

このクエリをリファクタリングする必要があります。 2回参加するか2つのクエリを使用するかは、ほとんど関係ありません。 2回参加すると、次のようになります。

SELECT something 
FROM posts 
INNER JOIN tag_map ON tag_map.id = posts.id 
INNER JOIN tags ON tags.tag_id = tag_map.tag_id 
WHERE tags.tag IN ('tag1', ...) 

詳細については、converting subqueries to JOINsのMySQLマニュアルを参照してください。

ヒント:EXPLAIN SELECTは、オプティマイザがクエリを処理する方法を示します。 DEPENDENT SUBQUERYが表示されている場合は、リファクタリングする必要があります。

+1

+1依存サブクエリのヒント – jclozano

2

次を使用して、それを改善することができます:

SELECT something 
FROM posts 
INNER JOIN tag_map ON tag_map.id = posts.id 
INNER JOIN tags 
ON tags.tag_id=tag_map.tag_id 
WHERE <tablename>.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6') 

だけ*あなたが必要なものだけを選択して使用していないことを確認してください。あなたはMySQLでは<テーブル名>

+0

これは私たちが** JOIN **と呼ぶものです。 –

+0

ええ、内部結合を2回、少なくとも私はin節よりも速いと思います – jclozano

1

結合は結果のフィルタリングを行います。最初の結合は第1のON条件を満足する結果を保持し、第2の条件は第2のON条件の最終結果を与える。

SELECT something 
FROM posts 
INNER JOIN tag_map ON tag_map.id = posts.id 
INNER JOIN tags ON tags.tag_id = tag_map.tag_id AND tags.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6'); 

あなたは、スタックオーバーフロー上のこれらの議論を見ることができます:

question1 question2

は、時間の複雑さを減らすのに役立ちますし、サーバーの安定性を高めましょう。サブクエリを変換するため

情報が参加:

link1 link2link3

関連する問題