首页 > 其他分享 >limit offset慢查询学习

limit offset慢查询学习

时间:2023-02-26 13:35:19浏览次数:38  
标签:查询 索引 limit 二叉树 offset id 主键

转自:https://cloud.tencent.com/developer/article/1962276

1.用法 

1. select* from article LIMIT 1,3

2.select * from article LIMIT 3 OFFSET 1

均表示略过第一条,取第2,3,4条数据。

2.慢查询原因

在offset很大时,会非常慢。它是先一直一条一条读取到10100条,然后再根据offset的设置,舍弃前10000条记录,返回后面的100条记录。 

原因:MySQL的数据存储并不是一个数组,可以直接根据下标获取第X位。即使给你搜索的字段加了索引,也只是使用该字段的值去建立一个新的N叉排序树(索引二叉树),来方便快速找到数据位置。所以并不能在O(1)时间知道第N个数在什么位置,而是O(N)需要从头开始遍历叶子结点链表,通过遍历计数来获取第N个数。

如果查找的where字段不是主键,而是自己创建的辅助索引,那么就会先根据辅助索引的叶子结点(存储主键索引,包含主键id)再去遍历主键索引B+数来获取到行的值。

为什么要查这些无效数据?

 //没太看懂是为什么,过于深奥,以后有机会再了解。

3.解决办法

3.1 利用主键id缩小范围

select * from table where id > 10000 limit 100;
  • 直接查主键二叉树并获取其节点上的数据;
  • 用大于的条件,从而利用好N叉排序树的特性,快速查找到数据的起始节点,然后获取其后的100条记录数据即可。这和offset找第100001条节点的实现机制有本质区别。(在20W的数据量级下,经过测试查询性能可以提升43倍。)

3.2 子查询

适用于必须要查询辅助索引N叉树的场景。

如果用非主键的索引去遍历,会导致两次对二叉树的查询操作:先查索引二叉树找到节点的主键,再查主键索引二叉树取具体数据。

select * from table where update_time < CURDATE() limit 100 offset 10000;

//上述慢查询可替换为
select * from table where id in (select id from table where update_time < CURDATE()) limit 100 offset 10000;

 子查询是根据辅助索引去查的,而主查询只根据了主键去查。在子查询中并不会真正去访问主键索引二叉树获取数据,因为只查询主键id,直接在辅助索引的叶子结点上就可以拿到,所以免去了10000次无效查询。在子查询获取到id后,再用IN查询去在主键索引二叉树上遍历数据。(这种做法虽然也要查询10000条无用的数据,但由于是直接使用主键索引,所以比直接查询limit offset的做法会快两倍左右。//所以才快2倍,看起来效率也不怎么高。)

 

还有解法3,利用join,没太仔细看,以后用到的时候再了解。

 

标签:查询,索引,limit,二叉树,offset,id,主键
From: https://www.cnblogs.com/BlueBlueSea/p/17156538.html

相关文章

  • 《黑马旅游网》综合案例九 旅游线路查询
    参数传递header.html:(注入导入js/getParameter.js文件)<!--头部start--><scriptsrc="js/getParameter.js"></script><script>//给搜索按钮绑定单击事件,获取搜索输入......
  • ssm学习笔记23001-mybatis基础查询
    myBatis的基础查询单条或多条查询根据id查询单条数据,查询所有数据的列表集合,查询所有数据的条目,查询出单条数据返回值为map,查询多条数据返回值为列表,查询多条数据返回值......
  • MongoDB在银行海量历史订单交易数据查询中的应用(Spring boot + Bee)
    MongoDB在银行海量历史订单交易数据查询中的应用(Springboot+Bee)近年来,随着各种便捷支付方式的普及,银行账户交易数据呈现爆炸式增长,同时数据模型也在不断变化,传统关......
  • Iceberg 数据治理及查询加速实践
    数据治理Flink实时写入Iceberg带来的问题在实时数据源源不断经过Flink写入的Iceberg的过程中,Flink通过定时的Checkpoint提交snapshotcommit操作到Iceberg,......
  • select查询语句
    显示表结构(DESCRIBE/DESC)DESCRIBEemployees;DESCemployees; 列的别名(AS)SELECTemployee_idemp_idFROMemployees;#省略写法SELECTemployee_idASem......
  • 案例_分析&环境搭建与案例_实现_查询数据库
    案例_分析&环境搭建案例需求:1.提供index.html页面,页面中有一个省份下拉列表 2.当页面加载......
  • android stdio中marqueeRepeatLimit无法循环播放
    首先,这个控件需要得到焦点,因此来实现循环播放,因此我们要 等我们再次启动虚拟机时,我们能够发现再次点击文字,就能够使控件文字循环播放。 但是这样点击文字循环会让整......
  • 889~891 分析,环境搭建,实现查询数据库,redis缓存优化
    案例:案例需求:1.提供index.html页面,页面中有一个省份,下拉列表2.当页面加载完成后,发送ajax请求,加载说有省份   CREATEDATABASEday23;--......
  • PyMySQL查询
    title:PyMySQL查询author:杨晓东permalink:PyMySQL查询date:2021-10-0211:27:04categories:-投篮tags:-demoPyMySQLMySQL数据库_查询"""数据库查询操......
  • JAVAWEB-NOTE03-约束、数据库设计、多表查询、事务
    目录约束约束的概念约束的分类约束的演示外键约束数据库设计简介软件研发的步骤数据库设计概念数据库设计的步骤一对多(多对一)多对多一对一多表查询内连接外连接左外连接右......