2011-05-13 13 views
4

私は、MySQL 5.0,5.1,5.5で以下の一見単純なクエリをテストしたところ、非常に遅いことがわかりました。MySQLサブクエリは本当に遅いです...回避策?

select * from entry where session_id in 
    (select session_id from entry where created_at > [some timestamp]) 

複数のエントリは同じセッションIDを持つことができますが、異なるcreated_atタイムスタンプを持つことができます。 クエリは、created_atが指定されたタイムスタンプより大きい同じsession_idから少なくとも1つのエントリを持つすべてのエントリを取得するためのものです。

私は、同様のクエリでMySQLサブクエリのパフォーマンスの問題を話し、MySQLはサブクエリを依存クエリとみなし、外部クエリに対してフルテーブルスキャンを実行していることが分かりました。推奨される回避策は、次のようなものでした:

select * from entry where session_id in 
    (select session_id from 
     (select session_id from entry where created_at > [some timestamp]) 
    as temp) 

しかし、このハックは私にとってはうまくいかず、さらに遅くなります。

このクエリの書き方についてのご意見はありますか?

答えて

5

、この

SELECT e.* 
FROM (
     SELECT session_id, MAX(created_at) 
     FROM entry 
     GROUP BY 
       session_id 
     HAVING MAX(created_at) > $mytimestamp 
     ) ed 
JOIN entry e 
ON  e.session_id = ed.session_id 

(session_id, created_at)にインデックスを作成)、または本使用:

SELECT DISTINCT e.* 
FROM entry ed 
JOIN entry e 
ON  e.session_id = ed.session_id 
WHERE ed.created_at > $mytimestamp 

created_atsession_id上の2つの別々のインデックスを作成)

+0

あなたは男です。ありがとう! 私は2番目のクエリのようなものから始めましたが、別のものは除外しました。ワイルドカードを使用して結果セット全体に明確に適用できるかどうかはわかりませんでした。驚くばかり。 – n00b

1

方法について:あなたはすでにそれを持っていない場合

SELECT DISTINCT e2.* 
    FROM entry e1 
     INNER JOIN entry e2 
      ON e1.session_id = e2.session_id 
    WHERE e1.created_at > [some timestamp] 

created_atsession_idのインデックスは、おそらく同様に役立つだろう。あなたのデータの分布に応じて、

+0

あなたは 'group by e2.id'も必要です。そうしないと重複してしまいます。 –

+0

ありがとうございます。それは私が最初に試したことです、実際には。これは私に重複を与えていた。私はグループで使うことはなかった。または、別個のe2。*を使用することもできます。 – n00b

+0

訂正が追加されました。 –

3

ダブルサブクエリのトリックにも問題がありました。 btwこれは、(あなたのクエリに基づいて)私の仕事:

select * from entry where session_id in 
    (select (select session_id from entry where created_at > [some timestamp])) 

私の場合は元のクエリは、参加したり、それが0秒を要した修正ダブルサブクエリを持つ「普通の」二重のサブクエリのトリックを使用して、時間のために働くことができます: )

+1

これは非常に簡単に適用できるので非常に便利です!しかし、それはMySQLのこの動作が奇妙です... – Pisu

+1

これは、内部クエリが単一の結果を返す場合にのみ機能します。それ以外の場合は、 "副問合せが1行以上を返します"というエラーが表示されます。 – ecdeveloper