在 MySQL 中,LIMIT 10 通常比 LIMIT 100000000, 10 快得多。

为什么 LIMIT 100000000, 10 慢?

当你执行 LIMIT 100000000, 10 时,MySQL 需要:

  1. 找到前 100000000 条记录(但不返回)
  2. 然后返回接下来的 10 条记录

这意味着 MySQL 实际上需要处理 100000010 条记录,而不仅仅是 10 条。

相比之下,LIMIT 10 只需要找到并返回前 10 条记录。

深度分页优化方案

以下是几种优化深度分页的方法:

1. 使用游标分页(推荐)

使用上一页的最后一条记录的主键作为下一页的起点:

-- 第一页
SELECT * FROM table_name ORDER BY id ASC LIMIT 10;-- 假设最后一条记录的 id 是 100
-- 第二页
SELECT * FROM table_name WHERE id > 100 ORDER BY id ASC LIMIT 10;-- 第三页
SELECT * FROM table_name WHERE id > 110 ORDER BY id ASC LIMIT 10;
2. 延迟关联(Deferred Join)

只查询主键,然后通过内连接获取完整数据:

SELECT t.* FROM table_name t 
INNER JOIN (SELECT id FROM table_name ORDER BY id LIMIT 100000000, 10
) AS tmp ON t.id = tmp.id;
3. 使用覆盖索引

确保查询的字段都在索引中,避免回表操作:

-- 创建覆盖索引
CREATE INDEX idx_covering ON table_name (sort_column, id);-- 查询时只使用索引中的字段
SELECT id, sort_column FROM table_name ORDER BY sort_column LIMIT 100000000, 10;
4. 使用书签标记

记录上次查询的位置,避免使用 OFFSET:

-- 不推荐
SELECT * FROM posts ORDER BY created_at DESC LIMIT 1000000, 20;-- 推荐
SELECT * FROM posts WHERE created_at < '2023-01-01 12:00:00' 
ORDER BY created_at DESC LIMIT 20;

总结

  1. LIMIT 10LIMIT 100000000, 10 快得多
  2. 对于深度分页,建议使用游标分页或书签标记方式
  3. 尽量避免使用大的 OFFSET 值
  4. 合理使用索引和覆盖索引可以显著提高查询性能

这些优化技术可以显著提高大数据集的分页查询性能,特别是在 Web 应用中。