[已解决:查看编辑 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 vslimit 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)。关于它为什么这样做的任何见解?此外,我添加了一个索引帖子(创建日期,所有者用户 ID)并且性能没有明显差异。
Edit2:终于通过force index (idx_owneruserid)
在第一个子查询上使用它来工作。经验教训:当解释计划未按预期使用您的索引时,请使用强制索引。