私はクエリを実行しており、MySQLがそれほどゆっくりと実行している理由を理解するのに苦労しています。以下の3つのシナリオで、実際のクエリとEXPLAINを含めました。遅いMySQLクエリ - 最適化する方法?
最初のクエリは非常に実行が遅く(23秒)、where句から1つのフィールド(クエリ2)を削除すると、クエリは0.010秒で実行されます。これはTinyIntフィールドです(基本的にブール値0/1が格納されます)。
プロジェクト - > hasManyの - >マイルストーン - > hasManyの - >タスク
task_wishlistクエリ1 EXPLAIN QUERY 1
SELECT `tasks`.*,
task_wishlist.description AS item_description,
task_wishlist.created_at AS item_created_at
FROM `tasks`
LEFT JOIN `task_wishlist` ON `tasks`.`id` = `task_wishlist`.`task_id`
LEFT JOIN `milestones` ON `tasks`.`milestone_id` = `milestones`.`id`
LEFT JOIN `projects` ON `milestones`.`project_id` = `projects`.`id`
WHERE `task_wishlist`.`wishlist_id` = '527021'
AND `tasks`.`active` = '1'
AND `projects`.`active` = '1'
AND `milestones`.`active` = '1'
ORDER BY `task_wishlist`.`created_at` DESC
LIMIT 25;
/* Affected rows: 0 Found rows: 25 Warnings: 0 Duration for 1 query: 23.072 sec. (+ 0.040 sec. network) */
タスクとウィッシュリストの間のピボットテーブルです。
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: projects
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 997
filtered: 10.00
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: milestones
partitions: NULL
type: ref
possible_keys: PRIMARY,milestones_project_id_foreign
key: milestones_project_id_foreign
key_len: 4
ref: fusion.projects.id
rows: 3
filtered: 10.00
Extra: Using index condition; Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: tasks
partitions: NULL
type: ref
possible_keys: PRIMARY,tasks_milestone_id_foreign
key: tasks_milestone_id_foreign
key_len: 5
ref: fusion.milestones.id
rows: 5
filtered: 10.00
Extra: Using where
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: task_wishlist
partitions: NULL
type: ref
possible_keys: task_wishlist_wishlist_id_foreign,task_wishlist_task_id_foreign
key: task_wishlist_task_id_foreign
key_len: 4
ref: fusion.tasks.id
rows: 100
filtered: 0.28
Extra: Using where
4 rows in set, 1 warning (0.01 sec)
クエリ2(milestones.active除去)
SELECT `tasks`.*,
task_wishlist.description AS item_description,
task_wishlist.created_at AS item_created_at
FROM `tasks`
LEFT JOIN `task_wishlist` ON `tasks`.`id` = `task_wishlist`.`task_id`
LEFT JOIN `milestones` ON `tasks`.`milestone_id` = `milestones`.`id`
LEFT JOIN `projects` ON `milestones`.`project_id` = `projects`.`id`
WHERE `task_wishlist`.`wishlist_id` = '527021'
AND `tasks`.`active` = '1'
AND `projects`.`active` = '1'
/*AND `milestones`.`active` = '1'*/
ORDER BY `task_wishlist`.`created_at` DESC
LIMIT 25;
/* Affected rows: 0 Found rows: 25 Warnings: 0 Duration for 1 query: 0.028 sec. (+ 0.010 sec. network) */
クエリ2説明:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: task_wishlist
partitions: NULL
type: ref
possible_keys: task_wishlist_wishlist_id_foreign,task_wishlist_task_id_foreign
key: task_wishlist_wishlist_id_foreign
key_len: 4
ref: const
rows: 7224
filtered: 100.00
Extra: Using index condition; Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: tasks
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,tasks_milestone_id_foreign
key: PRIMARY
key_len: 4
ref: fusion.task_wishlist.task_id
rows: 1
filtered: 10.00
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: milestones
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,milestones_project_id_foreign
key: PRIMARY
key_len: 4
ref: fusion.tasks.milestone_id
rows: 1
filtered: 100.00
Extra: NULL
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: projects
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: fusion.milestones.project_id
rows: 1
filtered: 10.00
Extra: Using where
4 rows in set, 1 warning (0.00 sec)
クエリ3:削除projects.active = 1
SELECT `tasks`.*,
task_wishlist.description AS item_description,
task_wishlist.created_at AS item_created_at
FROM `tasks`
LEFT JOIN `task_wishlist` ON `tasks`.`id` = `task_wishlist`.`task_id`
LEFT JOIN `milestones` ON `tasks`.`milestone_id` = `milestones`.`id`
LEFT JOIN `projects` ON `milestones`.`project_id` = `projects`.`id`
WHERE `task_wishlist`.`wishlist_id` = '527021'
AND `tasks`.`active` = '1'
/*AND `projects`.`active` = '1'*/
AND `milestones`.`active` = '1'
ORDER BY `task_wishlist`.`created_at` DESC
LIMIT 25;
/* Affected rows: 0 Found rows: 25 Warnings: 0 Duration for 1 query: 0.027 sec. (+ 4.031 sec. network) */
クエリ3説明
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: task_wishlist
partitions: NULL
type: ref
possible_keys: task_wishlist_wishlist_id_foreign,task_wishlist_task_id_foreign
key: task_wishlist_wishlist_id_foreign
key_len: 4
ref: const
rows: 7224
filtered: 100.00
Extra: Using index condition; Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: tasks
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,tasks_milestone_id_foreign
key: PRIMARY
key_len: 4
ref: fusion.task_wishlist.task_id
rows: 1
filtered: 10.00
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: milestones
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: fusion.tasks.milestone_id
rows: 1
filtered: 10.00
Extra: Using where
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: projects
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: fusion.milestones.project_id
rows: 1
filtered: 100.00
Extra: Using index
4 rows in set, 1 warning (0.00 sec)
私はこのクエリが含まれるすべてのactive
フィールドで適切に実行させるために何ができますか?
これらの各フィールドに一意でないインデックスを作成して、それがまったく役立つかどうかを確認しましたか? – ekalyvio
この形式の説明は読みにくいですが、MySQLが扱う行の量は少ないです。これは、I/Oの問題がある可能性があることを意味します。機械的なハードドライブとデフォルトのMySQL設定を実行していますか? MySQLには、プロファイリングと呼ばれる追加のプロファイリングメカニズムがあります。 'SET PROFILING = 1;あなたの質問はここにあります。クエリー1のプロフィールを表示する。 SET PROFILING = 0; '。これにより、MySQLが舞台裏で行うすべてのステップが表示されます。盲目的に推測すると、あなたの 'innodb_buffer_pool_size'が低すぎるので、MySQLはHDDがI/Oを完了するのを待つ必要があります。これは遅いです。 – Mjh
テーブルとインデックスの定義は何ですか? –