在 MySQL 中,LIMIT 10
通常比 LIMIT 100000000, 10
快得多。
为什么 LIMIT 100000000, 10 慢?
当你执行 LIMIT 100000000, 10
时,MySQL 需要:
- 找到前 100000000 条记录(但不返回)
- 然后返回接下来的 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;
总结
LIMIT 10
比LIMIT 100000000, 10
快得多- 对于深度分页,建议使用游标分页或书签标记方式
- 尽量避免使用大的 OFFSET 值
- 合理使用索引和覆盖索引可以显著提高查询性能
这些优化技术可以显著提高大数据集的分页查询性能,特别是在 Web 应用中。