2012-04-13 21 views
2

this wiki articleを読むと、MySQLデータベースのインデックス付きの列でIN()句を使用するとSELECTパフォーマンスが低下することがわかりました。私の質問は、どのようにIN()句を使用しないように、その機能を維持しながらクエリを書き直すことができますか?IN()句でクエリを最適化する

私のクエリは次のとおりです。

SELECT 
    `Route`.`route_id`, `Route`.`order`, `Route2`.`order` 
FROM 
    `routes` AS `Route` 
INNER JOIN 
    `routes` AS `Route2` 
ON `Route`.`route_id` = `Route2`.`route_id` 
WHERE 
    `Route`.`station_line_id` IN ([10 values]) AND 
    `Route2`.`station_line_id` IN ([10 values]) AND 
    `Route`.`order` <= `Route2`.`order` 
GROUP BY ` 
    `Route`.`station_line_id`, `Route2`.`station_line_id`, (`Route2`.`order` - `Route`.`order`) 

と私は(route_id、station_line_id、station_idとLINE_ID)、id列が主キーであることを(表は単なる読み取り専用で、一度生成されたすべての列をインデックス化しています、すべてを索引付けする心配はありません)。 IN()句の[10 values]は、カンマで区切られます(例:IN(1, 2, ..., 10))。

基本的には、テーブルルートテーブルを自己結合し、結果をグループ化して目的のレコードを取得します。他の結合は、関連するデータの検索に使用されます。

InnoDBストレージエンジンを使用して、パフォーマンス上の理由から30秒を超えて同様のクエリを実行します。 MyISAMを使用すると、私は5秒を超える。しかし、私は結果がより速くフェッチされると信じています。私はテーブルに〜450万レコードあります。

+0

クエリを少しフォーマットするのに気をつけますか? –

+0

私の質問を編集しました、申し訳ありません。 – linkyndy

+0

IN(1,3,47、... 89)または 'IN(SELECT column FROM table) 'という10個の値はありますか? –

答えて

1

「ハッシュインデックス」を使用して、このようなクエリで最高のパフォーマンスを得ることができます。 '標準'索引はB +ツリーで、log(n)時間内のエントリを検索できます.nは表の行数です。また、並べ替え順序も維持されるため、... WHERE station_line_id > 14などのクエリを効率的に実行できるので、Order列で使用するクエリを効率的に処理できます。

ただし、IN句を使用している場合は、同等のもののみを探しています。その場合、B +ツリーはあなたの "[10値]"のすべてを別々に検索しなければならないので、明らかに5〜30秒かかるm * log(n)の時間がかかります。

ハッシュインデックスは、テーブル内の行数に(理論上)依存しない一定の時間(非常に高速)で同等のエントリを検索するために使用されます。テーブル。ハッシュインデックスの欠点は、<>のようなクエリを使用することはできませんが、IN句の中で実行しているものと同等のクエリでは最も速いことです。station_line_idです。

編集:特にMySQLの場合、一般的なデータベースエンジンのHASHインデックスはサポートされていません。 MEMORYエンジンまたはHEAPエンジンを使用できる場合は、HASHインデックスを使用することができます。メモリ内のすべてのデータを使用すると、パフォーマンスがかなり向上する可能性があります。試してみる価値。

+0

私は現在共有ホストにいます。そのような量のデータをメモリに格納することはオプション(または?)ではないと思います。 – linkyndy

+1

MyISAMとInnoDBにハッシュインデックスはありません。 –

+0

あなたのデータ構造によっては、一発の価値があるかもしれません。私は2.7GBのデータと1.1GBのインデックスに適合する4500万行のテーブルを持っています。その速度では、あなたのテーブルは約.27 + .11 GB <= 400MBのメモリしか必要としません。私はあなたのサーバの要求が何であるか分かりませんが、512MBはVPSが持つメモリの無理な量ではありません。それがあなたのためのオプションであるかどうかはわかりませんが、パフォーマンスのスピードアップを保証できます。 –