我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL的ref有什么用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL的ref有什么用

这篇文章主要介绍“MySQL的ref有什么用”,在日常操作中,相信很多人在MySQL的ref有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL的ref有什么用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

 回忆一下查询成本

对于一个查询来说,有时候可以通过不同的索引或者全表扫描来执行它,MySQL优化器会通过事先生成的统计数据,或者少量访问B+树索引的方式来分析使用各个索引时都需要扫描多少条记录,然后计算使用不同索引的查询成本,最后选择成本最低的那个来执行查询。

创建场景

假如我们现在有一个表t,它的表结构如下所示:

CREATE TABLE t (     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,     key1 VARCHAR(100),     common_field VARCHAR(100),     INDEX idx_key1 (key1) ) ENGINE=InnoDB CHARSET=utf8;

这个表包含3个列:

  • id列是自增主键

  • key1列用于存储字符串,我们为key1列建立了一个普通的二级索引

  • common_field列用于存储字符串

现在该表中共有10000条记录:

mysql> SELECT COUNT(*) FROM t; +----------+ | COUNT(*) | +----------+ |    10000 | +----------+ 1 row in set (2.65 sec)

其中key1列为'a'的记录有2310条:

mysql> SELECT COUNT(*) FROM t WHERE key1 = 'a'; +----------+ | COUNT(*) | +----------+ |     2310 | +----------+ 1 row in set (0.83 sec)

key1列在'a'到'i'之间的记录也有2310条:

mysql> SELECT COUNT(*) FROM t WHERE key1 > 'a' AND key1 < 'i'; +----------+ | COUNT(*) | +----------+ |     2310 | +----------+ 1 row in set (1.31 sec)

现在我们有如下两个查询:

查询1:SELECT * FROM t WHERE key1 = 'a';  查询2:SELECT * FROM t WHERE key1 > 'a' AND key1 < 'i';

按理说上边两个查询需要扫描的记录数量是一样的,MySQL查询优化器对待它们的态度也应该是一样的,也就是要么都使用二级索引idx_key1执行它们,要么都使用全表扫描的方式来执行它们。不过现实是貌似查询优化器更喜欢查询1,而比较讨厌查询2。查询1的执行计划如下所示:

# 查询1的执行计划 mysql> EXPLAIN SELECT * FROM t WHERE key1 = 'a'\G *************************** 1. row ***************************            id: 1   select_type: SIMPLE         table: t    partitions: NULL          type: ref possible_keys: idx_key1           key: idx_key1       key_len: 303           ref: const          rows: 2310      filtered: 100.00         Extra: NULL 1 row in set, 1 warning (0.04 sec)

查询2的执行计划如下所示:

# 查询2的执行计划 mysql> EXPLAIN SELECT * FROM t WHERE key1 > 'a' AND key1 < 'i'\G *************************** 1. row ***************************            id: 1   select_type: SIMPLE         table: t    partitions: NULL          type: ALL possible_keys: idx_key1           key: NULL       key_len: NULL           ref: NULL          rows: 9912      filtered: 23.31         Extra: Using where 1 row in set, 1 warning (0.03 sec)

很显然,查询优化器决定使用idx_key1二级索引执行查询1,而使用全表扫描来执行查询2。

为什么?凭什么?同样是扫描相同数量的记录,凭什么我range访问方法就要比你ref低一头?设计MySQL的大叔,你为何这么偏心...

解密偏心原因

世界上没有无缘无故的爱,也没有无缘无故的恨。这事儿还得从索引结构说起。比方说idx_key1二级索引结构长这样:

MySQL的ref有什么用

原谅我们把索引对应的B+树结构弄了一个极度精简版,我们忽略掉了页的结构,只保留了叶子节点的记录。虽然极度精简,但是我们还是保留了一个极其重要的特性:B+树叶子节点中的记录是按照索引列的值从小到大排序的。对于二级索引idx_key1来说:

  • 二级索引叶子节点的记录只保留key1列和id列

  • 二级索引记录是先按照key1列的值从小到大的顺序进行排序的。

  • 如果key1列的值相同,则按照主键值,也就是id列的值从小到大的顺序进行排序。

也就是说,对于所有key1值为'a'的二级索引记录来说,它们都是按照id列的值进行排序的。对于查询1:

查询1: SELECT * FROM t WHERE key1 = 'a';

由于查询列表是*  ,也就是说我们需要通过读取到的二级索引记录的id值执行回表操作,到聚簇索引中找到完整的用户记录(为了去获取common_field列的值)后才可以将记录发送到客户端。对于所有key1列值等于'a'的二级索引记录,由于它们是按照id列的值排序的,所以:

  • 前一次回表的id值所属的聚簇索引记录和下一次回表的id值所属的聚簇索引记录很大可能在同一个数据页中

  • 即使前一次回表的id值所属的聚簇索引记录和下一次回表的id值所属的聚簇索引记录不在同一个数据页中,由于回表的id值是递增的,所以我们很大可能通过顺序I/O的方式找到下一个数据页,也就是说这个过程中很大可能不需要很大幅度的移动磁头就可以找到下一个数据页。这可以减少很多随机I/O带来的性能开销。

综上所述,执行语句1时,回表操作带来的性能开销较小。

而对于查询2来说:

查询2: SELECT * FROM t WHERE key1 > 'a' AND key1 < 'i';

由于需要扫描的二级索引记录对应的id值是无序的,所以执行回表操作时,需要访问的聚簇索引记录所在的数据页很大可能就是无序的,这样会造成很多随机I/O。所以如果使用idx_key1来执行查询1和查询2,执行查询1的成本很显然会比查询2低,这也是设计MySQL的大叔更钟情于ref而不是range的原因。

MySQL的内部实现

MySQL优化器在计算回表的成本时,在使用二级索引执行查询并且需要回表的情境下,对于ref和range是很明显的区别对待的:

  • 对于range来说,需要扫描多少条二级索引记录,就相当于需要访问多少个页面。每访问一个页面,回表的I/O成本就加1。

比方对于查询2来说,需要回表的记录数是2310,因为回表操作而计算的I/O成本就是2310。

  • 对于ref来说,回表开销带来的I/O成本存在天花板,也就是定义了一个上限值:

double worst_seeks;

这个上限值的取值是从下边两个值中取较小的那个:

比方对于查询1来说,回表的记录数是2310,按理说计算因回表操作带来的I/O成本也应该是2310。但是由于对于ref访问方法,计算回表操作时带来的I/O成本时存在天花板,会从全表记录的十分之一(也就是9912/10=991,9912为估计值)以及聚簇索引所占页面的3倍(本例中聚簇索引占用的页面数就是97,乘以3就是291)选择更小的那个,本例中也就是291。

  • 全表记录数的十分之一(此处的全表记录数属于统计数据,是一个估计值)

  • 聚簇索引所占页面的3倍

小贴士:在成本分析的代码中,range和index、all是被分到一类里的,ref是亲儿子,单独分析了一波。不过我们也可以看到,设计MySQL的大叔在计算range访问方法的代价时,直接认为每次回表都需要进行一次页面I/O,这是十分粗暴的,何况我们的实际聚簇索引总共才97个页面,它却将回表成本计算为2310,这也是很不精确的。

到此,关于“MySQL的ref有什么用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL的ref有什么用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

mysql中explain ref的用法是什么

在MySQL中,EXPLAIN语句用于分析查询语句的执行计划,包括了查询语句将如何执行、使用了哪些索引、表的访问顺序等信息。其中,EXPLAIN语句的结果中会包含一个ref列,用于显示查询中使用的索引或表的连接条件。ref列显示了所使用的
mysql中explain ref的用法是什么
2024-05-13

mysql中explain ref的特点有哪些

ref是指查询中使用了索引来进行表间关联的操作,可以提高查询效率。ref通常用于连接表中的外键列或者唯一索引列,用于快速定位需要关联的记录。ref操作是一种高效的表关联方式,可以减少查询时的数据扫描量,提高查询性能。ref的使用需要根
mysql中explain ref的特点有哪些
2024-05-13

vue遮罩和ref的使用方法是什么

这篇文章主要讲解了“vue遮罩和ref的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue遮罩和ref的使用方法是什么”吧!1、创建conform.vue,其内容如下:
2023-07-05

React中的ref怎么使用

这篇文章主要介绍“React中的ref怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React中的ref怎么使用”文章能帮助大家解决问题。1. ref 的理解与使用对于 Ref 的理解,要从
2023-07-04

mysql是什么有什么用

mysql 是一款开源关系数据库管理系统(rdbms),用于存储和管理数据。mysql 广泛用于 web 应用程序、电子商务和数据仓储等各种领域,因为它具有存储数据、管理数据、保障数据安全、可扩展性、跨平台兼容性和开源的优点。什么是 MyS
mysql是什么有什么用
2024-06-02

C++11中std::ref和std::cref的作用是什么

这篇文章给大家分享的是有关C++11中std::ref和std::cref的作用是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、源码准备本文是基于gcc-4.9.0的源代码进行分析,std::ref和st
2023-06-15

mysql的mvcc有什么作用

MySQL的MVCC(Multi-Version Concurrency Control)是一种并发控制机制,它在读取和写入数据时,允许数据库同时存在多个版本的数据。这种机制可以提高数据库的并发性能和可靠性,同时减少数据冲突和锁竞争。MV
mysql的mvcc有什么作用
2024-04-24

Vue3.0中Ref与Reactive的区别是什么

这篇文章主要介绍“Vue3.0中Ref与Reactive的区别是什么”,在日常操作中,相信很多人在Vue3.0中Ref与Reactive的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue3.0中
2023-06-20

Vue中Ref与Reactive的区别是什么

今天小编给大家分享一下Vue中Ref与Reactive的区别是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ref与Re
2023-06-05

mysql installer有什么用

mysql installer 是一款工具,简化了 mysql 数据库的安装、配置和管理。它的用途包括:安装和卸载 mysql创建和管理数据库配置服务器设置管理插件和扩展导入和导出数据备份和恢复MySQL Installer 的用途MyS
mysql installer有什么用
2024-06-02

mysql锁有什么用

mysql 锁是控制数据库资源并发访问的机制,防止数据冲突。类型包括表锁、行锁、页锁和意向锁。锁级别从共享锁(允许并发读取)到独占锁(只允许当前会话访问)不等。mysql 使用 mvcc 机制,通过维护数据的多个版本,允许并发事务同时读取数
mysql锁有什么用
2024-06-02

vue3中的ref、reactive怎么使用

本篇内容主要讲解“vue3中的ref、reactive怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue3中的ref、reactive怎么使用”吧!reactive()基本用法在 Vu
2023-07-05

编程热搜

目录