简单三步,解决SQL分页查询慢的问题

239 阅读2分钟

前言:

当数据量变大时,LIMIT 1000000, 10 这种分页查询会越来越慢。别担心!掌握这三个简单技巧,轻松优化。

当数据量变大时,如:LIMIT 1000000, 10 这种分页查询会越来越慢。别担心!掌握这三个简单技巧,轻松优化。

❌ 传统分页为什么慢?

SELECT * FROM users ORDER BY id LIMIT 1000000, 10; -- 越往后越卡

原因:数据库需要先扫描前1000010条数据,再丢掉前100万条,最后返回10条。


✅ 优化方案一:游标分页(推荐)

适用场景:顺序翻页(如APP无限滚动)

-- 第一页(取最新10条)
SELECT * FROM users ORDER BY id DESC LIMIT 10; 

-- 下一页(用上一页最后一条的ID)
SELECT * FROM users 
WHERE id < 上一页最后ID  -- 关键锚点
ORDER BY id DESC 
LIMIT 10;

优点:速度飞快!查询时间与数据量无关查询时间恒定,与数据量无关

  • 避免跳页时的性能悬崖
    ⚠️ 限制
  • 仅支持顺序翻页(适合无限滚动场景)

✅ 优化方案二:延迟关联

适用场景:需要跳页查询(如后台管理系统)

SELECT users.* 
FROM users
JOIN (
    SELECT id          -- 先查主键(更快)
    FROM users 
    ORDER BY create_time DESC
    LIMIT 1000000, 10  -- 只扫描索引
) AS tmp ON users.id = tmp.id;

优点:利用索引减少数据扫描量

  • 减少大字段回表开销
  • 利用覆盖索引加速

✅ 优化方案三:加对索引

无论用哪种方法,索引都是关键

-- 为排序字段创建索引(必做!)
CREATE INDEX idx_create_time ON users(create_time DESC); 

-- 复合索引效果更佳
CREATE INDEX idx_time_id ON users(create_time DESC, id);

🚀 一句话总结

  1. 顺序翻页 → 用游标分页(WHERE id < ?)
  2. 跳页查询 → 用延迟关联(先查ID再关联)
  3. 所有情况 → 务必创建排序字段索引!

小测试:优化这个慢查询

SELECT * FROM products 
ORDER BY views DESC 
LIMIT 200000, 10;

答案

-- 方案1:游标分页(需记录上一页最后views值)
SELECT * FROM products 
WHERE views < 上一页最后值 
ORDER BY views DESC LIMIT 10;

-- 方案2:延迟关联
SELECT p.* 
FROM products p
JOIN (
    SELECT id 
    FROM products 
    ORDER BY views DESC 
    LIMIT 200000, 10
) tmp ON p.id = tmp.id;

提示:百万元据以上建议结合业务设计(如限制最大页码)