奇怪的MySQL查询性能

时间:2013-03-21 18:55:38

标签: mysql

[解决:看编辑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)来实现它。获得的经验教训:当解释计划未按预期使用您的指数时,请使用强制指数。

0 个答案:

没有答案