HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Identical query, tables, but different EXPLAIN and performance

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
tablesbutqueryidenticaldifferentperformanceandexplain

Problem

I have two tables 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.