背景

一个行数为4亿条的表。

查询50000000~50000010行之间的数据。发现查询时间达到20s!!!

查询执行计划发现,需要进行全表扫描,没有索引。

但是,sbtest1这个表是有索引的

为什么mysql没有选择索引,而是全表扫描呢?

分析

mysql select 语法

SELECT[ALL | DISTINCT | DISTINCTROW ][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT][SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr] ...[into_option][FROM table_references[PARTITION partition_list]][WHERE where_condition][GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]][HAVING where_condition][WINDOW window_name AS (window_spec)[, window_name AS (window_spec)] ...][ORDER BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][LIMIT {[offset,] row_count | row_count OFFSET offset}][into_option][FOR {UPDATE | SHARE}[OF tbl_name [, tbl_name] ...][NOWAIT | SKIP LOCKED]| LOCK IN SHARE MODE][into_option]into_option: {INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name] ...
}

https://dev.mysql.com/doc/refman/8.0/en/select.html

offset 实现

MySQL的limit m n工作原理就是先读取前面m+n条记录,然后抛弃前m条,读后面n条想要的,所以m越大,偏移量越大,性能就越差。
https://cloud.tencent.com/developer/article/1505252

解决

在网上找到一个解决办法:可以把limit的offset当做where条件,这样mysql直接走索引,通过B+树直接定位到offset位置。类似于看书用书签标记下看到哪里的思路。

查询执行计划发现的确如此

如果使用非聚簇索引,也可以达到相同的效果

引申

比如:订单表、商品表,如果想做到分页效果、并提高用户体验,选择这种优化会有很大的提升。

就好比openstack的开源项目trove模块就有此设计,通过marker参数来保证一直分页的offset。

marker的使用逻辑为:

  • 本次查询的最后一条记录标记为next_marker,
  • 将next_marker作为api结果的一部分返回给用户,
  • 用户下次再请求这个api时,把next_marker赋值给marker传入进来

实现逻辑

  • 由于trove支持多种数据库,所以mysql user这类url需要通过注册的方式添加

    https://github.com/openstack/trove/blob/master/trove/extensions/routes/mysql.py#L48

  • def index方法是/users的controller层实现,在这里调用了models.Users.load(context)方法,第一个参数是context,这个参数是trove封装的上下文里面包含一些基本信息。

    https://github.com/openstack/trove/blob/master/trove/extensions/mysql/service.py#L64

  • 从上面controller层,调用到了models.User.load(context)方法,经过几次转换,调用到client.list_users(marker)方法参数带有marker。调用流程Users.load() -> load_via_context() -> Users.load_with_client(context.marker) -> client.list_users(marker)

    https://github.com/openstack/trove/blob/master/trove/extensions/mysql/models.py#L182

  • client.list_users的实现(manager层)

    https://github.com/openstack/trove/blob/master/trove/guestagent/datastore/manager.py#L833

  • list_users的service层实现,注释很详细,就不解释了。
    https://github.com/openstack/trove/blob/master/trove/guestagent/datastore/mysql_common/service.py#L340

mysql limit offset 原理分析与使用相关推荐

  1. mysql limit offset很大_MySQL查询中LIMIT的大offset导致性能低下浅析

    前言 我们大家都知道,mysql查询使用select命令,配合limit,offset参数可以读取指定范围的记录,但是offset过大影响查询性能的原因及优化方法 我们在业务系统中难免少不了分页的需求 ...

  2. .net mysql limit 分页原理_浅谈MySQL分页Limit的性能问题

    MySQL的分页查询通常通过limit来实现.limit接收1或2个整数型参数,如果是2个参数,第一个是指定第一个返回记录行的偏移量,第二个是返回记录行的最大数目.初始记录行的偏移量是0.为了与Pos ...

  3. MySQL表联接原理分析

    01 前言 用过MySQL的同学肯定都知道表联接,关键字即为 join ,使用的场景就是"当只查询一个表的信息不能满足我们需求"的时候,就需要用到两个甚至多个表联接查询.但是当不了 ...

  4. meb4.0.3(mysql enterprise backup)原理分析

    mysql企业版有两个值得付费的工具:mysql enterprise backup.thread pool. 下面来分析下MEB工作原理: 1.先来个全备 /usr/local/meb5.7/bin ...

  5. mysql limit offset

    Java代码   SELECT keyword FROM keyword_rank WHERE advertiserid='59' order by keyword LIMIT 2 OFFSET 1; ...

  6. MYSQL limit,offset 区别

    首先看下表 执行下面SQL SELECT* FROM`user` WHEREsex = 1 复制代码 结果 再来看下下面的SQL SELECT* FROM`user` WHEREsex = 1 LIM ...

  7. MySQL子查询原理分析

    01 前言 子查询,通俗解释就是查询语句中嵌套着另一个查询语句.相信日常工作中接触到 MySQL 的同学都了解或使用过子查询,但是具体它是怎样实现的呢? 查询效率如何? 这些恐怕好多人就不太清楚了,下 ...

  8. MySQL索引实现原理分析

    目前大部分数据库系统及文件系统都采用B-Tree(B树)或其变种B+Tree(B+树)作为索引结构.B+Tree是数据库系统实现索引的首选数据结构.在MySQL中,索引属于存储引擎级别的概念,不同存储 ...

  9. Mysql的常见面试题 + 索引原理分析

    今天给大家分享一篇干货,面试必备之Mysql索引底层原理分析 Mysql索引的本质 Mysql索引的底层原理 Mysql索引的实战经验 面试 问:数据库中最常见的慢查询优化方式是什么? 同学A:加索引 ...

最新文章

  1. 浪潮集团执行总裁王柏华:这次人工智能产业发展大潮“是真的”
  2. python下载的文件放在哪里的-Python下载文件的方法
  3. 分辨出谁在浏览Youtube、土豆
  4. java 调用 dll 乱码_java调用c++ dll出现中文乱码
  5. 没事随便写写——matlab图像与矩阵的转换与存储为txt文件
  6. 栈空间_Linux中的进程栈和线程栈
  7. 学会了这些技术,你离BAT大厂不远了
  8. 计算机电子琴音乐,电脑电子琴软件
  9. 私藏的18个黑科技网站,想找什么软件就找什么软件!!!
  10. 高光谱遥感图像处理与信息提取综述
  11. P2298 Mzc和男家丁的游戏
  12. E430 win7 下安装黑苹果系统
  13. 分类堆叠柱状图顺序排列及其添加合适条块标签
  14. 服务器系统迁移服务收费,服务器数据库迁移也收费
  15. 【Java】Spring 教程
  16. (平衡)kd树的创建与搜索
  17. velocity 将字符串切割按每隔3位加逗号,map集合遍历,字符串拼接,
  18. Simscape Multiby学习笔记5——在Multibody中建立控制器-驱动力-传感器
  19. 遥感影像匀色镶嵌分幅处理
  20. 清华大学刘知远组:文本分类任务中,将知识融入Prompt-tuning过程

热门文章

  1. 计算机网络:网络安全(网络支付安全)
  2. git tag的用法及意义
  3. 河北对外经贸职业学院计算机怎么样,河北对外经贸职业学院怎么样、好不好
  4. 讯飞录音笔SR702,全新功能提升工作效率
  5. 每周汇报 - 树叶的图像分类
  6. undefined reference to `__gxx_personality_sj0'错误解决办法
  7. (Python)识别和定位车道线
  8. IRIS 2021 技术文档 First Look 12--技术概要:.NET Object Persistence with XEP
  9. [附源码]java毕业设计宠物狗领养网站
  10. 静态页面练习——百度搜索页面