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

  • 相关阅读:
    Hadoop学习1:概述、单体搭建、伪分布式搭建
    第一次pta认证P测试C++
    改进粒子滤波的无人机三维航迹预测方法附Matlab代码
    channel 转移数据
    预测和分类钻孔的毛刺钻孔切削ANN预测
    2024Python二级
    C进阶 - 指针进阶
    Gitlab: PHP项目CI/CD实践
    [ffmpeg系列] 从应用的角度学习ffmpeg
    数据库之索引
  • 原文地址:https://blog.csdn.net/sunquan291/article/details/126282239