• 分页查询的SQL优化


    一、问题背景

    在数据库中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器哦。

    当一个表数据有几百万的数据的时候成了问题!

    如 * from table limit 0,10 这个没有问题
    当 limit 200000,10 的时候数据读取就很慢
    limit10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,而性能的问题就在这里。

    二、优化思路

    上面分页语句 limit10000,20,前面扫描出的10000都是浪费的,有没有办法避免这种浪费

    参考如下SQL语句(PG数据库)

    --查询10条记录,即500-510,由于排序了,最后一条ltp_id为6de468ef-d781-431b-ae4e-0edb96fb371d/odu/ochttp_bi-1/11/0/10
    select * from ltp_basic_info order by ltp_id limit 10 offset 500;
    
    --再查询10条记录,即510-520
    select * from ltp_basic_info order by ltp_id limit 10 offset 510;
    
    --再查询10条记录,即510-520,优化后的语句
    select * from ltp_basic_info where ltp_id>'6de468ef-d781-431b-ae4e-0edb96fb371d/odu/ochttp_bi-1/11/0/10'  order by ltp_id  limit 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基本思路 是借助了排序和比较,一次性过滤到不需要的数据

    三、进一步

    当分页查询里,增加了过滤条件时,则上面的优化则会失效,数据不连续。

    select * from ltp_basic_info where ltp_id like '6%' order by ltp_id limit 10 offset 20;
    
    • 1

    这个同样会扫瞄之前多余的10条全量数据,一个优化手段如下,先只查询ltp_id

    select * from (select ltp_id from ltp_basic_info where ltp_id like '6%' order by ltp_id limit 10 offset 20) tempId left join ltp_basic_info b on tempId.ltp_id=b.ltp_id;
    
    • 1

    四、总结

    • 当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢,你需增加order by,并且order by字段需要建立索引
    • 如果使用子查询去优化LIMIT的话,则子查询必须是连续的,某种意义来讲,子查询不应该有where条件,where会过滤数据,使数据失去连续性。

    参考:https://www.cnblogs.com/azhaozhao/articles/15080807.html

  • 相关阅读:
    Springboot晋韵戏剧点播网站毕业设计源码112304
    rpm包常用命令指南
    字符编码个人理解
    基于Python的汉语分词系统
    南卡火力全开,发布骨传导百元旗舰标杆,升级蓝牙5.3,内置4G存储,开启运动新体验!
    开发板搭建NFS文件系统
    代餐粉产业分析:中国市场销售额增长至116.94亿元
    学习day1 c++
    JavaEE——Http请求和响应,https的加密
    【Hack The Box】linux练习-- Magic
  • 原文地址:https://blog.csdn.net/sunquan291/article/details/126282239