patternsqlMinor
Identical query, tables, but different EXPLAIN and performance
Viewed 0 times
tablesbutqueryidenticaldifferentperformanceandexplain
Problem
I have two tables
+--------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| id | int(9) | NO | PRI | NULL | |
| user_id | int(10) | NO | MUL | NULL | |
| level_name | varchar(20) | NO | | NULL | |
| user_name | varchar(45) | NO | | NULL | |
| rating | decimal(3,2) | NO | | 2.50 | |
| votes | int(5) | NO | | 0 | |
| plays | int(5) | NO | | 0 | |
| date_published | date | NO | MUL | NULL | |
| user_comment | varchar(255) | YES | | NULL | |
| playable_character | int(2) | NO | MUL | 1 | |
| is_featured | tinyint(1) | NO | MUL | 0 | |
+--------------------+--------------+------+-----+---------+-------+
+----------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------+------+-----+---------+-------+
| user_id | int(8) | NO | PRI | NULL | |
| level_id | int(8) | NO | PRI | NULL | |
+----------+--------+------+-----+---------+-------+
I have my local dev environment and the production servers. This query:
SELECT id, level_name, date_published, rating
FROM levels
WHERE id IN (SELECT level_id FROM users_favorites WHERE user_id = 2);
runs very fast locally (around 0.0x seconds) and very slow on production (~15 seconds). The EXPLAIN's are different. On local:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users_favorites ref uniq_user_level,idx_user idx_user 4 const 21 "Using index"
1 SIMPLE levels eq_ref PRIMARY PRIMARY 4 users_favorites.level_id 1 "Using w
levels and users_favorites+--------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| id | int(9) | NO | PRI | NULL | |
| user_id | int(10) | NO | MUL | NULL | |
| level_name | varchar(20) | NO | | NULL | |
| user_name | varchar(45) | NO | | NULL | |
| rating | decimal(3,2) | NO | | 2.50 | |
| votes | int(5) | NO | | 0 | |
| plays | int(5) | NO | | 0 | |
| date_published | date | NO | MUL | NULL | |
| user_comment | varchar(255) | YES | | NULL | |
| playable_character | int(2) | NO | MUL | 1 | |
| is_featured | tinyint(1) | NO | MUL | 0 | |
+--------------------+--------------+------+-----+---------+-------+
+----------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------+------+-----+---------+-------+
| user_id | int(8) | NO | PRI | NULL | |
| level_id | int(8) | NO | PRI | NULL | |
+----------+--------+------+-----+---------+-------+
I have my local dev environment and the production servers. This query:
SELECT id, level_name, date_published, rating
FROM levels
WHERE id IN (SELECT level_id FROM users_favorites WHERE user_id = 2);
runs very fast locally (around 0.0x seconds) and very slow on production (~15 seconds). The EXPLAIN's are different. On local:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users_favorites ref uniq_user_level,idx_user idx_user 4 const 21 "Using index"
1 SIMPLE levels eq_ref PRIMARY PRIMARY 4 users_favorites.level_id 1 "Using w
Solution
Just make a simple join. Sub-queries does not provide the best result quite often
EXPLAIN SELECT l.id, l.level_name, l.date_published, l.rating
FROM levels AS l
INNER JOIN users_favorites AS uf
ON uf.level_id = l.id
WHERE l.user_id = 2;Code Snippets
EXPLAIN SELECT l.id, l.level_name, l.date_published, l.rating
FROM levels AS l
INNER JOIN users_favorites AS uf
ON uf.level_id = l.id
WHERE l.user_id = 2;Context
StackExchange Database Administrators Q#54084, answer score: 3
Revisions (0)
No revisions yet.