チケットの購入を示すデータベース〜800k個のレコードがあります。すべてのテーブルはInnoDBです。スロークエリは、次のとおりです。MySQLの低速クエリの最適化
SELECT e.id AS id, e.name AS name, e.url AS url, p.action AS action, gk.key AS `key`
FROM event AS e
LEFT JOIN participation AS p ON p.event=e.id
LEFT JOIN goldenkey AS gk ON gk.issuedto=p.person
WHERE p.person='139160'
OR p.person IS NULL;
このクエリは、それゆえp.person
の引用PDOから来ています。 JOIN
およびWHERE
で使用されるすべての列が索引付けされます。 p.event
は、e.id
に制限された外部キーであり、gk.issuedto
およびp.person
は、上記の表に拘束されている外部キーであるperson.id
です。これらはすべてINT
です。テーブルe
は小さく、わずか10行です。表p
は〜500,000行で、gk
は空です。
このクエリは、人の詳細ページで実行されます。すべてのイベントのリストを取得したい場合は、参加行がある場合は参加し、ゴールデンキー行がある場合はゴールデンキーがある場合。
スロークエリログを提供します:
Query_time: 12.391201 Lock_time: 0.000093 Rows_sent: 2 Rows_examined: 466104
EXPLAIN SELECT
が与える:
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+
| 1 | SIMPLE | e | ALL | NULL | NULL | NULL | NULL | 10 | |
| 1 | SIMPLE | p | ref | event | event | 4 | msadb.e.id | 727 | Using where |
| 1 | SIMPLE | gk | ref | issuedto | issuedto | 4 | msadb.p.person | 1 | |
+----+-------------+-------+------+---------------+----------+---------+----------------+------+-------------+
をこのクエリでは、将来的に与えられたp.person
その後、< 0.05sのための最初の実行に7〜12秒で動作します。 OR p.person IS NULL
を削除しても、クエリ時間は改善されません。 p
のサイズが〜20kから〜500k(古いデータのインポート)に増加したとき、このクエリは右に減速しました。
パフォーマンスを向上させる方法についてご意見はありますか?全体的な目的を覚えているのは、すべてのイベントのリストを取得することです。参加行がある場合は参加し、ゴールデンキー行がある場合はゴールデンキーがある場合。複数のクエリがより効率的になるなら、私はそれを行うことができます。にやにや笑いのために
p.eventとe.id、gk.issuedtoとp.personで結合を行っているのを見て、それらの列にインデックスを作成すると役に立ちます。 ...遅いタグ...あなたは私の一日を作った。 – bdares
ありがとう@bdares、あなたがタグを楽しんでうれしい;)。私はそれをリストアップしていませんでしたが、実際には 'e.id'、' gk.issuedto'と 'p.person'はすべてインデックスされています。 – mjec