• 分页查询的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

  • 相关阅读:
    亲手将TP-LINK路由器改装成交换机使用
    【Hack The Box】windows练习-- acute
    傅里叶变换在图像处理中的应用
    ogg怎么转换成mp3格式?
    视频流PS打包方式详解
    xss.pwnfunction.com靶机 Warmups
    分享demo:Vue3 使用element plus + vue-i18实现国际化
    Llama.cpp工具main使用手册
    Uniapp自定义启动图在线生成storyboard(适用于Uniapp)
    java毕业设计大学生心愿墙系统Mybatis+系统+数据库+调试部署
  • 原文地址:https://blog.csdn.net/sunquan291/article/details/126282239