首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何改进MySQL中的限制子句

问如何改进MySQL中的限制子句
EN

Stack Overflow用户
提问于 2015-04-15 11:34:11
回答 1查看 364关注 0票数 3

我有一个有10k行的posts表,我想按此创建分页。因此,我有一个关于这个目的的查询:

代码语言:javascript
复制
SELECT post_id
    FROM posts
    LIMIT 0, 10;

当我Explain这个查询时,我得到了下一个结果:

​

​

所以我不明白为什么MySql需要遍历9976行才能找到前10行?如果有人帮助我优化这个查询,我将非常感激。

我也知道这个主题MySQL按/限制性能排序:迟行查找,但是即使我将查询修改到下一个查询,问题仍然存在:

代码语言:javascript
复制
SELECT  t.post_id
FROM    (
        SELECT  post_id
        FROM    posts
        ORDER BY
                post_id
        LIMIT 0, 10
        ) q 
JOIN    posts t 
ON      q.post_id = t.post_id

​

​

更新

@pala_'s的解决方案对于上述简单情况非常有用,但现在我正在用inner join测试更复杂的查询时,我的目的是将注释表与post表连接起来,不幸的是,当我解释时,新的查询仍然遍历9976行。

代码语言:javascript
复制
Select comm.comment_id 
from comments as comm 
    inner join (
        SELECT post_id 
        FROM posts 
        ORDER BY post_id 
        LIMIT 0, 10
    ) as paged_post on comm.post_id = paged_post.post_id;  

你知道MySQL行为的原因是什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-15 11:43:45

试试这个:

代码语言:javascript
复制
SELECT post_id
    FROM posts
    ORDER BY post_id DESC
    LIMIT 0, 10;

不管怎么说,通过LIMIT进行分页都没有什么意义,而且它应该可以解决您的问题。

代码语言:javascript
复制
mysql> explain select * from foo;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | foo   | index | NULL          | PRIMARY | 4       | NULL |   20 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> explain select * from foo limit 0, 10;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | foo   | index | NULL          | PRIMARY | 4       | NULL |   20 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> explain select * from foo order by id desc limit 0, 10;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | foo   | index | NULL          | PRIMARY | 4       | NULL |   10 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

关于您对注释联接的最后评论。你有comment(post_id)的索引吗?通过我的测试数据,我得到了以下结果:

代码语言:javascript
复制
mysql> alter table comments add index pi (post_id);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select c.id from  comments c inner join (select id from posts o order by id  limit 0, 10) p on c.post_id = p.id;
+----+-------------+------------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+------------+-------+---------------+---------+---------+------+------+--------------------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |   10 |                          |
|  1 | PRIMARY     | c          | ref   | pi            | pi      | 5       | p.id |    4 | Using where; Using index |
|  2 | DERIVED     | o          | index | NULL          | PRIMARY | 4       | NULL |   10 | Using index              |
+----+-------------+------------+-------+---------------+---------+---------+------+------+--------------------------+

对于表格大小的参考:

代码语言:javascript
复制
mysql> select count(*) from posts;
+----------+
| count(*) |
+----------+
|    15021 |
+----------+
1 row in set (0.01 sec)

mysql> select count(*) from comments;
+----------+
| count(*) |
+----------+
|     1000 |
+----------+
1 row in set (0.00 sec)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29649131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档