処理に時間がかかる MySQL クエリを最適化しようとしています。users テーブルと purchase テーブルの 2 つのテーブルがあるとします。両方のテーブルには、約 20,000 行あります。
mysql>
SELECT NOW(),u.id
FROM users u
LEFT JOIN purchases p
ON p.user_id = u.id
WHERE
p.website_id = 1234
ORDER BY u.total_paid DESC
LIMIT 10;
+---------------------+-------+
| NOW() | id |
+---------------------+-------+
*snip*
+---------------------+-------+
10 rows in set (0.06 sec)
超高速ではありませんが、かなり機敏です。に変更する以外に何も変更u.id
しないu.*
と、劇的に遅くなります:
mysql>
SELECT NOW(),u.*
FROM users u
LEFT JOIN purchases p
ON p.user_id = u.id
WHERE
p.website_id = 1234
ORDER BY u.total_paid DESC
LIMIT 10;
+---------------------+-------+
*snip*
+---------------------+-------+
10 rows in set (0.37 sec)
「まあ、絶対に使用しないでください」と言う前にselect *
、追加するフィールドが増えるほど、その時間までゆっくりと忍び寄ることを考慮してください。つまり、選択するフィールドの半分に名前を付けると、クエリが約 0.20 秒で実行され、フィールドにはフィールドがありません。 users テーブルが より大きいですvarchar(255)
。
ただし、比較的きびきびしたクエリから ID を取得すると、単純に次のようになります。
mysql>
SELECT *
FROM users
WHERE id IN (*snip*);
+---------------------+-------+
*snip*
+---------------------+-------+
10 rows in set (0.01 sec)
したがって、私の 2 つのクエリ: select u.id
plusselect u.* where id in
は、同様のクエリであると想定するものよりも高速です。一体何?
詳細情報: users テーブルには約 30 のフィールドがあります。繰り返しますが、どのフィールドもvarchar(255)
詳細情報:両方のクエリの EXPLAIN は次のとおりです。
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: p
type: ref
possible_keys: PRIMARY,user_id_index,website_id_index,website_user_id_index,website_created_index,website_type_created_index,website_type_index,purchase_user_id_type_index,user_id_website_id_index,website_id_user_id_index
key: website_id_user_id_index
key_len: 9
ref: const
rows: 9976
Extra: Using where; Using index; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: u
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: database.p.user_id
rows: 1
Extra:
編集一時/ファイルソートを使用しているため、ユーザーから * を選択する必要があり、最終的な結果セットにどの行が含まれるかがわからない可能性がありますか? 些細な余分なデータのように見えるかもしれませんが、実際には、テーブルの大きなチャンクを選択することの違いですか? これが正しい場合、何か提案はありますか?