I'm running a query, and struggling to understand why MySQL is runing it so slowly. I've included the actual queries and the EXPLAIN in 3 scenarios below.
The first query is very slow to run (23 seconds), but removing just one field (Query 2) from the where clause causes the query to run in 0.010s. This is a TinyInt field (essentially a boolean 0/1 is stored).
projects -> hasMany -> milestones -> hasMany -> tasks
task_wishlist is a pivot table between tasks and wishlists
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) */
Query 1 EXPLAIN:
*************************** 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)
Query 2 (remove 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) */
Query 2 Explain:
*************************** 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)
Query 3: remove 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) */
Query 3 Explain
*************************** 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)
What can I do to make this query run properly with all active fields included?
profiling.SET PROFILING = 1; Your query goes here ; SHOW PROFILE FOR QUERY 1; SET PROFILING = 0;. This will show you all steps that MySQL undertakes behind the scenes. Guessing blindly: yourinnodb_buffer_pool_sizeis too low, so MySQL needs to wait for HDD to complete its I/O, which is slow.using temporaryin the first explain, but not the others.