1

[已解决:查看编辑 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)在第一个子查询上使用它来工作。经验教训:当解释计划未按预期使用您的索引时,请使用强制索引。

4

0 回答 0