常见的面试必备之MySQL索引底层原理分析:

  • MySQL索引的本质
  • MySQL索引的底层原理
  • MySQL索引的实战经验

面试

1)问题:数据库中最常见的慢查询优化方式是什么?

  回答:加索引

2)问题:为什么加索引能优化慢查询?

  回答:因为索引是一种优化查询的数据结构,比如MySQL中的索引是B+树实现的,而B+树就是一种数据结构,可以优化查询速度,可以利用索引快速查找数据,所以能优化查询!

3)你知道哪些数据结构可以提高查询速度?

  回答:哈希表、完全平衡二叉搜索树、B树、B+树等等;

4)那这些数据结构既然都能优化查询速度,那MySQL为何选择使用B+树?

  (1)哈希表的特点

  假设有这么一张表,表名为:users

  现在对name字段建立hash索引

  

  注意字段值所对应的数组下标是哈希算法随机计算出来的,所以可能会出现哈希冲突。那么对于这样的一个索引结构,现在来执行下面的SQL语句:

    select * from users where name = '周瑜';

  可以直接对 '周瑜' 按哈希算法算出一个数组下标,然后可以直接从数据中取出数据并拿到锁对应的那一行数据的地址,进而在数据表文件中查询那一行数据。

  那么如果现在执行下面的SQL语句:

    select * from users where name > '周瑜';   

  此时则无能为力,因为哈希表的特点就是可以快速的精确查询,但是不支持范围查询!

  (2)完全平衡二叉搜索树

  还是上面的表数据用完全平衡二叉树表示如下图(为了简单,数据对应的地址就不画在图中)

  

  图中的每一个节点实际上应该有四部分:

    1. 左指针,指向左子树

    2. 键值(key)

  3. 键值所对应数据的存储地址(data域中的值)

    4. 右指针,指向右子树

  需注意:完全平衡二叉搜索树是有序的,简单的说就是 "左边的小于右边的",假如我们现在来查找 '周瑜' ,需要查找2次(第一次操作,第二次周瑜),比哈希表要多一次。而且由于完全平衡二叉搜索树是有序的,所以支持范围查找。

  (3)B树

  还是上面的表示数据用B树表示如下图(为了简单,数据对应的地址就不画在图中了)

  

  可以发现同样的元素,B树表示的要比完全平衡二叉搜索树要 "矮",原因在于B树中的一个节点可以存储多个元素!

  (4)B+树

  还是上面的表示数据用B+树表示如下图(为了简单,数据对应的地址就不画在图中了)

  

  我们可以发现同样的元素,B+树的表示要比B树要 "胖",原因在于B+树中的非叶子节点会冗余一份在叶子节点中,并且叶子节点之间用指针相连!

  B+树作为索引的优势

  这里我们用“反证法”,假如我们现在就用完全平衡二叉搜索树作为索引的数据结构,我们来看一下有什么不妥的地方。实际上,索引也是很“大”的,因为索引也是存储元素的,我们的一个表的数据行数越多,那么对应的索引文件其实也是会很大的,实际上也是需要存储在磁盘中的,而不能全部都放在内存中,所以我们在考虑选用哪种数据结构时,我们可以换一个角度思考,哪个数据结构更适合从磁盘中读取数据,或者哪个数据结构能够提高磁盘的IO效率。回头看一下完全平衡二叉搜索树,当我们需要查询“张飞”时,需要以下步骤

  1. 从磁盘中取出“曹操”到内存,CPU从内存取出数据进行笔记,“张飞”<“曹操”,取左子树(产生了一次磁盘IO)

  2. 从磁盘中取出“周瑜”到内存,CPU从内存取出数据进行笔记,“张飞”>“周瑜”,取右子树(产生了一次磁盘IO)

  3. 从磁盘中取出“孙权”到内存,CPU从内存取出数据进行笔记,“张飞”>“孙权”,取右子树(产生了一次磁盘IO)

  4. 从磁盘中取出“黄忠”到内存,CPU从内存取出数据进行笔记,“张飞”=“张飞”,找到结果(产生了一次磁盘IO)

  同理,回头看一下B树,我们发现只发送三次磁盘IO就可以找到“张飞”了,这就是B树的优点:一个节点可以存储多个元素,相对于完全平衡二叉树所以整棵树的高度就降低了,磁盘IO效率提高了。而B+树是B树的升级版,只是把非叶子节点冗余一下,这么做的好处是 为了提高范围查找的效率

到这里可以总结出来,Mysql选用B+树这种数据结构作为索引,可以提高查询索引时的磁盘IO效率,并且可以提高范围查询的效率,并且B+树里的元素也是有序的。

5)问题:一个B+树的节点中到底存储多少个元素合适呢?

  回答:B+树中一个节点为一页或页的倍数最为合适。因为如果一个节点的大小小于1页,那么读取这个节点的时候其实也会读出1页,会造成资源的浪费;如果一个节点的大小大于1页,比如1.2页,那么读取这个节点的时候会读出2页,也会造成资源的浪费;所以为了不造成资源的浪费,最后把一个节点的大小控制在1页、2页、3页、4页等倍数页大小最为合适!

6)MySQL中B+树的一个节点大小为多大?

  回答:一页,这里说的 "页" 是MySQL自定义的单位(其实和操作系统类似),MySQL的Innodb引擎中一页的默认大小是16K(如果操作系统中一页大小是4K,那么MySQL中1页 = 操作系统中的4页),这样存取数据的时候都是一页一页的获取索引文件中节点数据的!

7)为什么B+树中一个节点为1页(16K)就够了?

  回答:先来看一下MySQL中利用B+树来实现索引的数据结构具体实现:

  MySQL中MyISM和Innodb使用B+树

  

  通常我们认为B+树的非叶子节点不存储数据,只有叶子节点才存储数据;而B树的非叶子节点和叶子节点都会存储数据,会导致非叶子节点存储的索引值会更少,树的高度相对会比B+树高,平均的I/O效率会比较低,所以使用B+树作为索引的数据结构,再加上B+树的叶子节点之间使用了指针相连,也方便进行范围内查找,上图的data区域两个存储引擎会有区别!

  MyISM中的B+树

  MyISQM中叶子节点的数据区域存储的是数据记录的地址

  主键索引

  

  辅助索引

  

  MyISAM存储引擎在使用索引查询数据时,会先根据索引查找到数据地址,再根据地址查询到具体的数据。并且主键索引和辅助索引没有太多区别。

  Innodb中的B+树

  Innodb中主键索引的叶子节点的数据区域存储的是数据记录,辅助索引存储的是主键值

  辅助索引

  

  Innodb中的主键索引和实际数据时绑定在一起的,也就是说Innodb的一个表一定要有主键索引,如果一个表没有手动建立主键索引,Innodb会查看有没有唯一索引,如果有则选用唯一索引作为主键索引,如果连唯一索引也没有,则会默认建立一个隐藏的主键索引(用户不可见)。另外,Innodb的主键索引要比MyISAM的主键索引查询效率要高(少一次磁盘IO),并且比辅助索引也要高很多。所以,我们在使用Innodb作为存储引擎时,我们最好:

  1. 手动建立主键索引

  2. 尽量利用主键索引查询

  回到我们的问题:为什么一个节点为1页(16K)就够了?

  对着上面Mysql中Innodb中对B+树的实际应用(主要看主键索引),可以发现B+树中的一个节点存储的内容是:

    1. 非叶子节点:主键 + 指针

    2. 叶子节点:数据

  那么,假设我们一行数据大小为1K,那么一页就能存16条数据,也就是一个叶子节点能存16条数据;再看非叶子节点,假设主键ID为bigint类型,那么长度为8B,指针大小在Innodb源码中为6B,一共就是14B,那么一页里就可以存储16K/14=1170个(主键+指针),那么一颗高度为2的B+树能存储的数据为:1170 * 16=18720条,一颗高度为3的B+树能存储的数据为:1170 * 1170 * 16=21902400(千万级条)。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据。所以也就回答了我们的问题,1页=16k这么设置是比较合适的,是适用大多数的企业的,当然这个值是可以修改的,所以也能根据业务的时间情况进行调整。

  

  

  

干货 MySQL常见的面试题 + 索引原理分析的更多相关文章

  1. 干货—MySQL常见的面试题+索引原理分析!

    目录 MySQL索引的本质 MySQL索引的底层原理 MySQL索引的实战经验 面试 问:数据库中最常见的慢查询优化方式是什么? 同学A:加索引. 问:为什么加索引能优化慢查询? 同学A:...不知道 ...

  2. mysql进阶(二十七)数据库索引原理

    mysql进阶(二十七)数据库索引原理 前言   本文主要是阐述MySQL索引机制,主要是说明存储引擎Innodb.   第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础.    ...

  3. MySQL学习(二)索引原理及其背后的数据结构

    首先区分几个概念: 聚集索引 主索引和辅助索引(即二级索引) innodb中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(sec ...

  4. MySQL 第五篇:索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

  5. mysql数据库补充知识7 索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

  6. Elasticsearch核心技术(四):索引原理分析

    本文探讨Elasticsearch的数据请求.路由和写入过程的原理,主要涉及ES的分布式存储架构.节点和副本的写入过程.近实时搜索的原因.持久化机制等. 4.1 ES存储架构 我们经常说,看一件事情千 ...

  7. MySql索引原理分析

    面试 问:数据库中最常见的慢查询优化方式是什么? 同学A:加索引. 问:为什么加索引能优化慢查询?同学A:...不知道同学B:因为索引其实就是一种优化查询的数据结构,比如Mysql中的索引是用B+树实 ...

  8. Elasticsearch-基础介绍及索引原理分析(转载)

    最近在参与一个基于Elasticsearch作为底层数据框架提供大数据量(亿级)的实时统计查询的方案设计工作,花了些时间学习Elasticsearch的基础理论知识,整理了一下,希望能对Elastic ...

  9. Elasticsearch-基础介绍及索引原理分析

    介绍 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 L ...

随机推荐

  1. QJsonObject 遍历

    遍历QjsonObject方式 方式一 QJsonObject::const_iterator it = l_obj.constBegin(); QJsonObject::const_iterator ...

  2. Dubbo系列之 (七)网络层那些事(2)

    辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...

  3. Linux命令行bash的快捷键

    提升效率 锁屏 Ctrl + s 敲什么命令没反应,但是敲上去了,屏幕上不做任何反应 Ctrl + q 再解锁 例如: 先Ctrl + s 锁屏 然后在命令行敲入 [root@C8-1 ~]# rm ...

  4. CentOS8 yum安装Mariadb10.4

    CentOS8 yum安装Mariadb10.4 https://downloads.mariadb.org/mariadb/repositories/#distro=CentOS&distr ...

  5. 文献管理软件 Zotero 安装、配置与使用

    简介 Zotero优缺点 使用Zotero作为主力文献管理工具的原因: 软件本身完全免费并且开源,不存在盗版问题 注册后本身只包括 300M 空间同步,但支持 WebDAV 同步,例如 Dropbox ...

  6. A. Arena of Greed 解析(思維)

    Codeforce 1425 A. Arena of Greed 解析(思維) 今天我們來看看CF1425A 題目連結 題目 略,請直接看原題. 前言 明明是難度1400的題目,但總感覺不是很好寫阿, ...

  7. OAuth2 快速入门

    1 OAuth简述 OAuth 2.0 是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源.应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源,并且资 ...

  8. 云计算管理平台之OpenStack网络服务neutron

    一.简介 neutron的主要作用是在openstack中为启动虚拟机实例提供网络服务,对于neutron来讲,它可以提供两种类型的网络:第一种是provider network,这种网络就是我们常说 ...

  9. python实现城市气候与海洋的关系研究

    城市气候与海洋的关系研究 关注公众号"轻松学编程"了解更多. 以下命令都是在浏览器中输入. cmd命令窗口输入:jupyter notebook 后打开浏览器输入网址http:// ...

  10. Java集合(类)框架(三)

    1. Map集合 相较于List和Set集合而言,Map集合所储存的数据为双列行,数据是以key和value为一个单位进行存储的,如在建立一个学生Map的时候,其中的数据应为 学号-姓名(key-va ...