作者  沈刚·沃趣科技数据库技术专家

出品  沃趣科技

| 简介

跳跃范围扫描是MySQL在8.0.13版本新增加的用于提高性能的新特性,跳跃范围扫描可以使以前部分无法使用到联合索引的SQL利用联合索引进行查询,并且可以更高效的利用联合索引,这对于使用MySQL联合索引进行查询的应用意义重大。

| 环境信息

  • MySQL版本:8.0.15

  • 操作系统版本:redhat-7.4

| 跳跃范围扫描

通过一个示例来解释跳跃范围扫描:

CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2));INSERT INTO t1 VALUES(1,1), (1,2), (1,3), (1,4), (1,5),(2,1), (2,2), (2,3), (2,4), (2,5);INSERT INTO t1 SELECT f1, f2 + 5 FROM t1;INSERT INTO t1 SELECT f1, f2 + 10 FROM t1;INSERT INTO t1 SELECT f1, f2 + 20 FROM t1;INSERT INTO t1 SELECT f1, f2 + 40 FROM t1;ANALYZE TABLE t1;EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40\G*************************** 1. row ***************************       id: 1  select_type: SIMPLE    table: t1   partitions: NULL     type: rangepossible_keys: PRIMARY      key: PRIMARY  key_len: 8      ref: NULL     rows: 53 filtered: 100.00    Extra: Using where; Using index for skip scan1 row in set, 1 warning (0.00 sec)

mysql> select version();+-----------+| version() |+-----------+| 8.0.15 |+-----------+1 row in set (0.00 sec)

在这个示例中,SELECT f1,f2 FROM t1 WHERE f2>40在8.0.13版本之前是通过索引全扫描的方式来获取最终的结果集,因为SELECT查询的字段全部都是索引的组成部分。MySQL通过索引全扫描获取所有的行记录,然后通过f2 > 40这个条件过滤,最终筛选出结果集返回给客户端。

众所周知,索引范围扫描的效率肯定是要高于索引全扫描的,在这个示例中,虽然查询条件是f2 > 40,属于范围查询,但是WHERE条件中不包含f1字段的的条件,所以无法使用索引范围扫描的方式过滤数据。在MySQL-8.0.13版本增加的跳跃范围扫描特性,就是针对类似的场景的优化,跳跃范围扫描在这个示例中实际是针对每一个f1字段的值,进行了范围扫描,即进行了多次范围扫描。 
针对这个示例,具体的跳跃范围扫描过程如下:

  1. 获取联合索引中第一个字段f1的第一个值:f1 = 1

  2. 将获取到的值和WHERE条件中的f2的条件组合:f1 = 1 AND f2 > 40

  3. 执行这个范围扫描查询

  4. 获取联合索引中第一个字段f1的第二个值:f1 = 2

  5. 将获取到的值和WHERE条件中的f2的条件组合:f1 = 2 AND f2 > 40

  6. 执行这个范围扫描查询

  7. 将两次范围扫描查询的结果合并返回给客户端

跳跃范围扫描实际就是将一些全扫描的场景拆分成多个范围扫描,利用范围扫描的效率高于全扫描的效率,最终实现提高SQL效率。

在这个示例中,比较有跳跃范围扫描特性的SQL执行计划以及没有跳跃范围扫描特性的SQL执行计划:

# 有跳跃范围扫描特性mysql> EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40\G*************************** 1. row ***************************       id: 1  select_type: SIMPLE    table: t1   partitions: NULL     type: rangepossible_keys: PRIMARY      key: PRIMARY  key_len: 8      ref: NULL     rows: 53 filtered: 100.00    Extra: Using where; Using index for skip scan1 row in set, 1 warning (0.00 sec)

# 没有跳跃范围扫描特性mysql> EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40\G  *************************** 1. row ***************************       id: 1  select_type: SIMPLE    table: t1   partitions: NULL     type: indexpossible_keys: NULL      key: PRIMARY  key_len: 8      ref: NULL     rows: 160 filtered: 33.33    Extra: Using where; Using index1 row in set, 1 warning (0.00 sec)

通过执行计划可以看到,有跳跃范围扫描特性的查询扫描的行数更少且过滤性更高。

| 使用限制以及场景

下面来说说跳跃范围扫描使用一些限制以及场景:

  • 表上至少存在一个联合索引([A_1,A_2...A_k],B_1,B_2...B_m,C,[,D_1,...,D_n]),其中A部分以及D部分可以为空,但是B和C部分不能为空。A_1,A_2..等代表字段值

  • 只针对单表查询

  • 查询中不包含GROUP BY或者DISTINCT

  • SELECT查询的字段全部被包含在索引组成部分,即符合覆盖索引规范

  • 前缀A_1,A_2...A_k部分必须是可以被相等的常量

  • 字段C上必须是一个范围条件,大于或大于等于,小于或小于等于

  • 允许在D字段上有过滤条件,但是必须和C上的范围条件一起使用

跳跃范围扫描默认是开启的,有两种方式可以关闭跳跃范围扫描特性:

  • 通过修改optimizer_switcher变量值,默认MySQL是将optimizer_switcher中的skip_scan设置为on的,可以通过将skip_scan设置为off关闭跳跃范围扫描

  • 通过Hint的方式关闭跳跃范围扫描特性:SELECT/*+ NO_SKIP_SCAN(t1 PRIMARY) */ f1, f2 FROM t1 WHERE f2 > 40;

对于使用了跳跃范围扫描特性的SQL,使用EXPLAIN查看其执行计划,可以看到:

  • 在执行计划输出的Extra一栏中有:Using index for skip scan

  • 在执行计划输出的possible_keys一栏中会显示可以使用到的索引

| 总结

跳跃范围扫描是对使用MySQL联合索引查询的SQL意义重大,能在使SQL查询效率更高,但是并不是使用到跳跃范围扫描就能代表SQL执行效率更高。在MySQL一些开发规范中,一般要求建立联合索引时将重复值少的字段放在联合索引前面,将重复值多的字段放在联合索引后面,方便SQL在使用联合索引时通过前面的字段快速过滤结果。但是在跳跃范围扫描特性中,是遍历前面字段的值,与后续字段的范围查询条件组合,进行范围扫描查询,那对于重复值少的字段会被拆分成多个范围扫描查询,在实际使用过程中并不一定会比索引全扫描效率更高。

所以个人觉得跳跃范围扫描适用于联合索引中前导列distinct值较少,后续字段选择过滤性又比较好的场景,能更好的发挥跳跃范围扫描的作用。

| 作者简介

沈 刚·沃趣科技数据库技术专家

熟悉MySQL数据库运行机制,丰富的数据库及复制架构故障诊断、性能调优、数据库备份恢复及迁移经验。

点击查看招聘信息

相关链接

如何清除创建失败的索引

MySQL分区如何迁移

故障排除 | enq:TX - index contention等待事件

浅谈编程范式

sysbench花式踩坑之三:自增值导致的锁等待

沃趣微讲堂 | Oracle集群技术(六):集群应用资源层

如果将relay_log_recovery设置为0会发生什么?(下)

谈谈代码——如何避免写出糟糕if...else语句

为何Binlog中同一个事务的event时间点会乱序?

Oracle中的并行系列(二):你设置的并行真的生效了吗?

Oracle集群技术 | 集群的自启动系列(一)

深入浅出Kubernetes网络:容器网络初探

更多干货,欢迎来撩~

mysql范围条件_MySQL8.0之跳跃范围扫描相关推荐

  1. mysql mgr简介_mysql8.0初探:(二)MySQL Group Replication-MGR集群简介

    mysql8.0初探:(二)MySQL Group Replication-MGR集群简介 发布时间:2020-06-12 23:59:17 来源:51CTO 阅读:49832 作者:arthur37 ...

  2. mysql sha256函数_MySQL8.0新特性——默认使用caching_sha2_password作为身份验证插件

    mysql5.8开始将caching_sha2_password作为默认的身份验证插件 该caching_sha2_password和 sha256_password认证插件提供比mysql_nati ...

  3. mysql.sock 初始化_mysql8.0 部署、初始化和创建实例

    环境信息: centos 7.4.1708 mysql 8.0.11 1.下载解压缩mysql包 cd /usr/local/ wget https://cdn.mysql.com//Download ...

  4. linux修改mysql临时密码_MySQL8.0修改临时密码

    解决MySQL8.0报错:Unknown system variable 'validate_password_policy' 一.问题描述 1.在安装MySQL8.0时,修改临时密码,因密码过于简单 ...

  5. eclipse mysql Xml配置_mysql8.0在eclipse中通过xml文件配置数据库连接池

    mysql8.0在eclipse中通过xml文件配置数据库连接池 1.关于Mysql8.0 2.数据库连接池(DBCP) 3.准备工作 4.配置context.xml 5.配置web.xml 6.调用 ...

  6. mysql 加字段_MySQL8.0大表秒加字段,是真的吗?

    前言: 很早就听说 MySQL8.0 支持快速加列,可以实现大表秒级加字段.笔者自己本地也有8.0环境,但一直未进行测试.本篇文章我们就一起来看下 MySQL8.0 快速加列到底要如何操作. 1.了解 ...

  7. mysql 注册驱动_mysql8.0以上版本注册驱动并建立数据库的连接公共代码

    String driverName = "com.mysql.jdbc.Driver"; String userName = "用户名"; String use ...

  8. mysql连接驱动_MySQL8.0数据库连接驱动问题

    在新电脑上安装了MySQL8.0,打开原来的一个项目去连接时,报如下错误 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionExce ...

  9. mysql jdbc百度_mysql8.0 jdbc连接注意事项

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 url增加参数useSSL 和时区 : jdbc:mysql://localhost:3306/mydb?useSSL=false&serverT ...

最新文章

  1. P1051 谁拿了最多奖学金
  2. 电子书推荐--《Python灰帽子》,python黑客编程
  3. 零售业创新服务:Kochhaus杂货店按照菜谱陈列商品
  4. 怎么打败腾讯[纯讨论]
  5. 常用的几个PHP加密函数
  6. 【英语学习】【Level 08】U03 My Choice L1 Good books are like good friends
  7. python列表的排序方法是_Python列表排序 reverse、sort、sorted 操作方法详解
  8. 杭电计算机17年复试真题详解
  9. ewebeditor for php任意文件上传漏洞
  10. 关于前几周项目进行的一些感受
  11. JAVA上百实例源码网站
  12. 敏感词库php数组,PHP 实现敏感词 / 停止词 过滤(附敏感词库),敏感类词语大全...
  13. 1 什么是机器学习(Machine Learning)?
  14. Mysql-学习笔记汇总
  15. 拒绝精神内耗,5个适合中年人的自学网站,让你脱胎换骨
  16. Z39.50客户端源代码(C#)
  17. 汉语拼音拼读的小技巧
  18. WSDM'23 | 工业界搜推广nlp论文整理
  19. 毕业两年,我完成了月薪3k到月薪13k的转变
  20. 【智力题】兄弟姐妹的性别

热门文章

  1. SQL Server 2008等登录用户只能看到自己的数据库设置办法
  2. 解决只可以上QQ却不可以上网问题
  3. 创建了一个.NET 技术的 Wiki 和论坛
  4. VisualSVN安装图解
  5. bzoj 4563 [Haoi2016]放棋子 错位排列+高精度
  6. Java_基础—用LinkedList模拟栈数据结构的集合并测试
  7. java.lang.UnsatisfiedLinkError: no XXX in java.library.path
  8. linux虚拟机网络配制方法及遇到问题的解决方法
  9. JGrid有用的收藏
  10. [恢]hdu 2186