首页 > 数据库 >SQL深度分页

SQL深度分页

时间:2024-04-15 13:46:34浏览次数:21  
标签:10 分页 SQL 深度 update 回表 limit time id

当查询语句的偏移量特别大的时候,查询效率就会变的很差,比如limit 10 offset 100 和limit 10 offset 100000的效率肯定是不一样的,后者会慢的多

那怎么解决呢?

先模拟一个例子,表结构如下

CREATE TABLE account (
  id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  name varchar(255) DEFAULT NULL COMMENT '账户名',
  balance int(11) DEFAULT NULL COMMENT '余额',
  create_time datetime NOT NULL COMMENT '创建时间',
  update_time datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (id),
  KEY idx_name (name),
  KEY idx_update_time (update_time)
)

查询语句如下

select id,name,balance from account where update_time < '2024-04-15' limit 10 offset 2000000;

 

 

 

 花了7.172秒,速度挺慢的,看下执行计划,走的是普通索引ids_update_time, 类型是range,Extra是Using index condition, 存在回表行为

 

 

链接:    执行计划怎么看

sql的执行顺序:from -> where -> group by -> having -> select -> order by -> limit

  

mysql先是执行from 和where,然后执行select,最后执行limit,所以这里会先根据where条件,通过index(ids_update_time)查出2000000+10条记录的主键(id),然后执行select,又因为select里面还包含了name和balance,这两个字段不会存在索引(ids_update_time)中,需要回表根据主键去查出这2000000+10条记录的id+name+balance,回表次数2000010次,最后进行limit(offset),丢弃掉2000000条,取最后的10

 

 

回表次数太多了,我们可以试着从回表次数来优化,如下,我们如果只取出id呢,只花了0.89s, 看下执行计划,不回表了,因为id直接就能在这个index里面拿到

 

 

我们已经得到了id,要得到id对应的name和balance,可以使用in或者inner join

先用in来试试(因为in子查询里面不能使用 limit,所以又套了一层),花了3.68秒,快了那么一点,还是不够,执行计划里挺复杂的

 

改用inner join 试试,只花了0.875秒,执行计划里面,先执行查询走idx_update_time索引(type为range,并且不回表),然后通过id进行inner join走的是主键索引(type为eq_ref)

 

到此为止,这个优化应该可以了,从7.172s优化到了0.875s

 

如果这里的查询条件从update_time改成create_time, 而且id是自增的,所以任何两条记录都会满足下面这个条件

记录a的create_time比记录b的create_time小,则一定存在a的id比b的id小

那我们可以只查出第一条满足记录的id,然后通过id比较来得到接下来的10条记录,同样的,看下执行计划,也是走索引idx_update_time没有回表,然后走主键索引,时间也是差不多的0.86s

 

 

 

 另外,如果id的变化情况和create_time是一致的(即任何两条记录,id较大的那条记录的create_time也较大),还可以这样

第一次查询是通过update_time来比较,并加上限制 limit 10 offset 0,

第二次查询可以通过传上一次返回值的最后一条记录的id(previous_id),可以通过where id > #{previous_id} limit 10 offset 10来查询

 

 

 

 

参考:

聊聊如何解决 MySQL 深分页问题 - 捡田螺的小男孩:https://juejin.cn/post/7012016858379321358

//普通索引

标签:10,分页,SQL,深度,update,回表,limit,time,id
From: https://www.cnblogs.com/huainanyin/p/18135274

相关文章

  • jmeter 连接 sqlserver 数据库
    1. 将下载好的 jar 包放在 jmeter/lib 目录下,测试计划中导入 jar 包 2.添加 JDBCConnectionConfiguration 配置,参数设置如下 3. 线程组中添加 JDBCRequest,请求中连接名字(test)和步骤2 中自定义的名字(test)保持一致 4. 点击运行,查询出对应的结果 问题回......
  • mysql的分区之key,hash分区
    1.hash分区HASH分区主要用来确保数据在预先确定数目的分区中平均分布,要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。hash分区所使用的字段一定要是主键!!createtable表名(.........)engine=MyISAMpartitionbyhash(算......
  • IFreeSql各数据库连接字符串格式
    IFreeSql各数据库连接字符串格式 DataTypeConnectionStringDataType.MySqlDataSource=127.0.0.1;Port=3306;UserID=root;Password=root;InitialCatalog=cccddd;Charset=utf8;SslMode=none;Minpoolsize=1DataType.PostgreSQLHost=192.168.164.10;Port=5432;Us......
  • Flask-SQLAlchemy
    Flask-SQLAlchemyFlask-SQLAlchemy是flask的一个拓展插件,专门添加对SQLAlchemy的支持(ORM,关系对象模型)。使用它可以在flask中使用对象直接与SQLAlchemy进行交互,大大简化了SQLAlchemy与flask结合使用的过程,提供了非常方便的一些操作对象,例如引擎、模型、会话、请求等......
  • 淘宝二面:MySQL里有2000万条数据,但是Redis中只存20万的数据,如何保证redis中的数据都是
    引言在当今互联网领域,尤其在大型电商平台如淘宝这样的复杂分布式系统中,数据的高效管理和快速访问至关重要。面对数以千万计的商品、交易记录以及其他各类业务数据,如何在MySQL等传统关系型数据库之外,借助内存数据库Redis的力量,对部分高频访问数据进行高效的缓存处理,是提升整个系统......
  • mysql交换两列数据
    mysql交换两列数据某ai上居然给出了下面这个语句,这语句是错误的,会把两列换成一样的数据UPDATEt_aSETcol1=col2,col2=col1;下面的语句是可行的updatet_aasa,t_basbseta.col1=b.col2,a.col2=b.col1wherea.id=b.id;下面是使用临时变......
  • 图解 SQL 执行顺序,通俗易懂!
      数据的关联过程from&join&wheregroupbyhaving&whereselectorderbylimit这是一条标准的查询语句: 这是我们实际上SQL执行顺序:我们先执行from,join来确定表之间的连接关系,得到初步的数据where对数据进行普通的初步的筛选groupby分组各组分别执行havi......
  • SQL Prompt 10安装与破解方法
    SQLPrompt10安装与破解方法Cooper写文章只是为了日常记录 4人赞同了该文章SQLPrompt10是一款SQLServer数据库开发工具,通过自动完成、代码补全等功能提高开发效率。但是,该软件需要付费购买,对于一些学生和个人开发者来说,价格较为昂贵。本文将......
  • .net core EF mysql 共享事务
     .netcoreEFmysql共享事务在.NETCore中使用EntityFramework(EF)Core与MySQL一起工作时,您可以使用System.Transactions的TransactionScope来创建一个可以跨多个数据库连接共享的事务。以下是一个简单的示例,展示了如何在.NETCore应用程序中使用EntityFramewo......
  • SQL SERVER锁(LOCK)知识及锁应用(转载)
    SQLSERVER锁(LOCK)知识及锁应用(转载)ChenSir°已于 2023-10-0915:10:48 修改阅读量2.1k收藏8点赞数1文章标签:数据库sqlserver于 2023-10-0915:07:09 首次发布  提示:这里所摘抄的关于锁的知识有的是不同sqlserver版本的,对应于特......