相同的查询、表,但不同的 EXPLAIN 和性能

Hal*_*000 6 mysql performance explain query-performance

我有两张桌子levelsusers_favorites

+--------------------+--------------+------+-----+ -------+-------+
| 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 |
+--------------------+--------------+------+-----+ -------+-------+
| 身份证 | 整数(9) | 否 | PRI | 空 | |
| 用户 ID | 整数(10) | 否 | 多| 空 | |
| 级别名称 | varchar(20) | 否 | | 空 | |
| 用户名 | varchar(45) | 否 | | 空 | |
| 评级 | 十进制(3,2) | 否 | | 2.50 | |
| 投票 | 整数(5) | 否 | | 0 | |
| 戏剧| 整数(5) | 否 | | 0 | |
| date_published | 日期 | 否 | 多| 空 | |
| 用户评论 | varchar(255) | 是 | | 空 | |
| playable_character | 整数(2) | 否 | 多| 1 | |
| is_featured | tinyint(1) | 否 | 多| 0 | |
+--------------------+--------------+------+-----+ -------+-------+
+------------+--------+------+-----+---------+------ -+
| 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 |
+------------+--------+------+-----+---------+------ -+
| 用户 ID | 整数(8) | 否 | PRI | 空 | |
| level_id | 整数(8) | 否 | PRI | 空 | |
+------------+--------+------+-----+---------+------ -+

我有我的本地开发环境和生产服务器。这个查询:

SELECT id、level_name、date_published、评级
FROM 级别
WHERE id IN (SELECT level_id FROM users_favorites WHERE user_id = 2);

在本地运行非常快(大约 0.0x 秒)并且在生产中非常慢(~15 秒)。EXPLAIN 是不同的。在本地:

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 “使用索引”
1 简单级别 eq_ref PRIMARY PRIMARY 4 users_favorites.level_id 1 “使用地点”

在生产方面:

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY 级别 ALL NULL NULL NULL NULL 3368988 “使用哪里”
2 "DEPENDENT SUBQUERY" users_favorites eq_ref uniq_user_level,idx_user uniq_user_level 8 const,func 1 "使用索引"

我知道数据是相同的,因为它是从相同的模式导入和导出的。我运行了 OPTIMIZE 并确保索引相同,尝试强制索引。没有任何效果。

我能发现的唯一区别是 MySQL 的版本:本地是 5.6.10,在生产中是 5.5.34-log。如果是这个原因,我会升级,但我想知道是否还有其他原因?或者如何对查询进行措辞,以便它总是首先通过子查询减少,就像它在本地一样:21 行而不是 3368988?

TIA

geo*_*j11 3

只需进行简单的连接即可。子查询并不经常提供最佳结果

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;
Run Code Online (Sandbox Code Playgroud)