[解决:看编辑2] 以下查询需要37秒才能完成 (此查询获取用户所做的第50个帖子和相应的创建日期)
SELECT p.id,
(SELECT id
FROM posts
WHERE owneruserid = p.id
ORDER BY creationdate
LIMIT 49, 1) AS post50id,
(SELECT creationdate
FROM posts
WHERE id = post50id)
FROM prol_users p
WHERE postcount >= 50
而以下需要30分钟才能完成(第5篇)
SELECT p.id,
(SELECT id
FROM posts
WHERE owneruserid = p.id
ORDER BY creationdate
LIMIT 4, 1) AS post5id,
(SELECT creationdate
FROM posts
WHERE id = post5id)
FROM prol_users p
WHERE postcount >= 50
请注意,这是我第一次运行查询,因此不涉及缓存。第一个查询与第二个查询之间的唯一区别是limit 49,
1 vs limit 4, 1
当查询限制为50行而不是限制为5行时,是否有任何理由需要花费较少的时间?
解释输出:
--Note: The faster one, limit 50
mysql> explain select p.id, (select id from posts where owneruserid = p.id order by creationdate limit 49,1) as post50id, (select creationdate from posts where id = post50id) from prol_users p where postcount >= 50;
+----+--------------------+-------+--------+--------------------------+-----------------+---------+------------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+--------------------------+-----------------+---------+------------+--------+-----------------------------+
| 1 | PRIMARY | p | ALL | NULL | NULL | NULL | NULL | 199026 | Using where |
| 3 | DEPENDENT SUBQUERY | posts | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | Using where |
| 2 | DEPENDENT SUBQUERY | posts | ref | idx_owneruserid,idx_ouid | idx_owneruserid | 5 | jagat.p.id | 11 | Using where; Using filesort |
+----+--------------------+-------+--------+--------------------------+-----------------+---------+------------+--------+-----------------------------+
3 rows in set (0.00 sec)
--Note: The slower one, limit 5
mysql> explain select p.id, (select id from posts where owneruserid = p.id order by creationdate limit 4,1) as post5id, (select creationdate from posts where id = post5id) from prol_users p where postcount >= 50;
+----+--------------------+-------+--------+--------------------------+------------------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+--------+--------------------------+------------------+---------+------+--------+-------------+
| 1 | PRIMARY | p | ALL | NULL | NULL | NULL | NULL | 199026 | Using where |
| 3 | DEPENDENT SUBQUERY | posts | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | Using where |
| 2 | DEPENDENT SUBQUERY | posts | index | idx_owneruserid,idx_ouid | idx_creationdate | 8 | NULL | 5 | Using where |
+----+--------------------+-------+--------+--------------------------+------------------+---------+------+--------+-------------+
3 rows in set (0.00 sec)
编辑:我测试了各种极限值,并注意到当极限从9,1变为10,1时性能会大幅提升。事实上,解释计划也会发生变化(到50年代)。对它为什么这么做的任何见解? 另外,我添加了一个索引帖子(creationdate,owneruserid),并且性能没有明显差异。
Edit2:最后通过在第一个子查询上使用force index (idx_owneruserid)
来实现它。获得的经验教训:当解释计划未按预期使用您的指数时,请使用强制指数。