gpt4 book ai didi

mysql - 如何改进MySQL中的Limit子句

转载 作者:可可西里 更新时间:2023-11-01 07:58:39 26 4
gpt4 key购买 nike

我有一个包含 10k 行的 posts 表,我想以此创建分页。所以我有下一个查询用于此目的:

SELECT post_id
FROM posts
LIMIT 0, 10;

当我解释那个查询时,我得到了下一个结果:

enter image description here

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

我也知道那个话题MySQL ORDER BY / LIMIT performance: late row lookups ,但即使我将查询修改为下一个,问题仍然存在:

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

enter image description here

更新

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

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 行为的原因是什么?

最佳答案

试试这个:

SELECT post_id
FROM posts
ORDER BY post_id DESC
LIMIT 0, 10;

通过 LIMIT 分页在没有排序的情况下没有多大意义,它应该可以解决您的问题。

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) 的索引吗?使用我的测试数据,我得到以下结果:

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 |
+----+-------------+------------+-------+---------------+---------+---------+------+------+--------------------------+

以及表格大小引用:

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)

关于mysql - 如何改进MySQL中的Limit子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29649131/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com