web-dev-qa-db-ja.com

600万行のテーブルでのMysqlのパフォーマンス

ある日、Hadoopを学習して、このすべてのデータを非構造化データベースに転送する必要があると思いますが、このような短期間でパフォーマンスが大幅に低下することに驚いています。

600万行弱のmysqlテーブルがあります。私はこのテーブルに対して非常に単純なクエリを実行しており、すべての正しいインデックスが設定されていると信じています。

クエリは

 SELECT date、time FROM events WHERE venid = '47975' AND date> = '2009-07-11' ORDER BY date 

説明が返されます

 idselect_typeテーブルタイプpossible_keyskey key_len ref rows Extra 
 1 SIMPLE updateshows range date_idx date_idx 7 NULL 648997 Using where 

そのため、私が知る限り正しいインデックスを使用していますが、このクエリの実行には11秒かかります。

データベースはMyISAMであり、phpMyAdminによるとテーブルは1.0GiBです。

ここに何かアイデアはありますか?

編集:date_idxは、日付列とvenid列の両方にインデックスを付けます。それらは2つの別々のインデックスである必要がありますか?

16
pedalpete

クエリがインデックスのみを使用することを確認したいので、インデックスが選択しているすべてのフィールドをカバーしていることを確認してください。また、これは範囲クエリに関係しているため、定数としてクエリされるため、インデックスの最初にvenidを指定する必要があります。したがって、次のように作成してインデックスを作成します。

ALTER TABLE events ADD INDEX indexNameHere (venid, date, time);

このインデックスを使用すると、クエリを完了するために必要なすべての情報がインデックスに含まれます。これは、うまくいけば、ストレージエンジンが、テーブル自体の内部を実際に検索することなく情報をフェッチできることを意味します。ただし、MyISAMはインデックスのリーフにデータを格納しないため、これを実行できない可能性があります。そのため、希望する速度の向上が得られない可能性があります。その場合は、テーブルのコピーを作成し、そのコピーでInnoDBエンジンを使用してみてください。そこで同じ手順を繰り返して、速度が大幅に向上するかどうかを確認します。 InnoDB doesフィールド値をインデックスリーフに格納し、インデックスをカバーできるようにします。

さて、クエリを説明すると、次のように表示されることを願っています。

mysql> EXPLAIN SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date;

id  select_type table  type  possible_keys        key       [..]  Extra
1   SIMPLE   events range date_idx, indexNameHere indexNameHere   Using index, Using where
42

Venidとdateにまたがるキーを追加してみてください(またはその逆、あるいはその両方...)

2
Greg

6Mの行テーブルは、ごく普通の手法で最適化できるはずだと思います。

専用のデータベースサーバーがあり、かなりの量のRAM(たとえば最小8G)があると仮定します。

RAMを効率的に使用するようにmysqlを調整したことを確認する必要があります。 32ビットOSを実行している場合は、実行しないでください。 MyISAMを使用している場合は、キーバッファーを調整して、RAMのかなりの割合を使用しますが、多すぎないようにします。

いずれの場合も、実稼働グレードのハードウェアで繰り返しパフォーマンステストを実行する必要があります。

2
MarkR

venid列にインデックスを付けてみてください。

1
Lucas Jones