返回顶部
首页 > 资讯 > 数据库 >MySQL的ref有什么用
  • 919
分享到

MySQL的ref有什么用

2024-04-02 19:04:59 919人浏览 八月长安
摘要

这篇文章主要介绍“Mysql的ref有什么用”,在日常操作中,相信很多人在mysql的ref有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”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有什么用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL的ref有什么用

本文链接: https://lsjlt.com/news/69478.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL的ref有什么用
    这篇文章主要介绍“MySQL的ref有什么用”,在日常操作中,相信很多人在MySQL的ref有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL的ref有什么用”...
    99+
    2024-04-02
  • mysql中explain ref的用法是什么
    在MySQL中,EXPLAIN语句用于分析查询语句的执行计划,包括了查询语句将如何执行、使用了哪些索引、表的访问顺序等信息。其中,E...
    99+
    2024-05-13
    mysql
  • mysql中explain ref的特点有哪些
    ref是指查询中使用了索引来进行表间关联的操作,可以提高查询效率。 ref通常用于连接表中的外键列或者唯一索引列,用于快速定位需要...
    99+
    2024-05-13
    mysql
  • React中的Ref是什么
    这篇文章主要介绍React中的Ref是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Intro在 React 项目中,有很多场景需要用到 Ref。例如使用 ref 属性获取 DO...
    99+
    2024-04-02
  • vue遮罩和ref的使用方法是什么
    这篇文章主要讲解了“vue遮罩和ref的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue遮罩和ref的使用方法是什么”吧!创建conform.vue,其内容如下:<t...
    99+
    2023-07-05
  • React中的ref怎么使用
    这篇文章主要介绍“React中的ref怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React中的ref怎么使用”文章能帮助大家解决问题。1. ref 的理解与使用对于 Ref 的理解,要从...
    99+
    2023-07-04
  • mysql是什么有什么用
    mysql 是一款开源关系数据库管理系统(rdbms),用于存储和管理数据。mysql 广泛用于 web 应用程序、电子商务和数据仓储等各种领域,因为它具有存储数据、管理数据、保障数据安...
    99+
    2024-06-02
    mysql linux macos
  • C++11中std::ref和std::cref的作用是什么
    这篇文章给大家分享的是有关C++11中std::ref和std::cref的作用是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、源码准备本文是基于gcc-4.9.0的源代码进行分析,std::ref和st...
    99+
    2023-06-15
  • vue中ref怎么用
    vue中ref的用法有三种,分别是:1.ref加在普通的元素上,用this.ref.name获取dom元素;2.ref加在子组件上,用this.ref.name 获取组件实例,可以使用组件的所有方法;3.利用v-for和ref获取一组数组或...
    99+
    2024-04-02
  • mysql的主键有什么用
    这篇文章主要介绍了mysql的主键有什么用,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。 (针对InnoDB引擎)我们实际生产环境可能...
    99+
    2024-04-02
  • MySQL中的mysqladmin有什么用
    本篇内容介绍了“MySQL中的mysqladmin有什么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • mysql的mvcc有什么作用
    MySQL的MVCC(Multi-Version Concurrency Control)是一种并发控制机制,它在读取和写入数据时,...
    99+
    2024-04-24
    mysql MVCC
  • Vue3.0中Ref与Reactive的区别是什么
    这篇文章主要介绍“Vue3.0中Ref与Reactive的区别是什么”,在日常操作中,相信很多人在Vue3.0中Ref与Reactive的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue3.0中...
    99+
    2023-06-20
  • Vue中Ref与Reactive的区别是什么
    今天小编给大家分享一下Vue中Ref与Reactive的区别是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ref与Re...
    99+
    2023-06-05
  • mysql notifier有什么用
    这篇文章主要介绍了mysql notifier有什么用,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。MySQL Notifier是什么?MySQ...
    99+
    2024-04-02
  • mysql有什么作用
    小编给大家分享一下mysql有什么作用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!众所周知,MySQL是一种关系数据库管理系统...
    99+
    2024-04-02
  • mysql有什么用处
    这篇文章将为大家详细讲解有关mysql有什么用处,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前...
    99+
    2024-04-02
  • MySQL-Proxy有什么用
    这篇文章主要为大家展示了“MySQL-Proxy有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL-Proxy有什么用”这篇文章吧。MySQL-P...
    99+
    2024-04-02
  • mysql installer有什么用
    mysql installer 是一款工具,简化了 mysql 数据库的安装、配置和管理。它的用途包括:安装和卸载 mysql创建和管理数据库配置服务器设置管理插件和扩展导入和导出数据备...
    99+
    2024-06-02
    mysql
  • mysql锁有什么用
    mysql 锁是控制数据库资源并发访问的机制,防止数据冲突。类型包括表锁、行锁、页锁和意向锁。锁级别从共享锁(允许并发读取)到独占锁(只允许当前会话访问)不等。mysql 使用 mvcc...
    99+
    2024-06-02
    mysql 并发访问
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作