常见的面试必备之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. spring boot:配置shardingsphere(sharding jdbc)使用druid数据源(druid 1.1.23 / sharding-jdbc 4.1.1 / mybatis / spring boot 2.3.3)

    一,为什么要使用druid数据源? 1,druid的优点 Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 但spring ...

  2. ps 批量kill进程

    Linux下批量kill掉进程   ps -ef|grep java|grep -v grep|cut -c 9-15|xargs kill -9 管道符"|"用来隔开两个命令,管 ...

  3. IntelliJ IDEA 15款 神级超级牛逼插件推荐(超赞,谁用谁知道)

    满满的都是干货  所有插件都是在 ctrl+alt+s 里的plugins 里进行搜索安装 1.CodeGlance 代码迷你缩放图插件 2. Codota 代码提示工具,扫描你的代码后,根据你的敲击 ...

  4. CPU:Central Processing Unit

    CPU执行计算任务时都需要遵从一定的规范,程序在被执行前都需要先翻译为CPU可以理解的语言.这种规范或语言就是指令集(ISA,Instruction Set Architecture). CPU 架构 ...

  5. 入门 第一个python可视化程序 基于pyqt5

    不得不说 py的GUI实在是太难上手了 我现在突然很怀念MFC VB c#这些东西了 因为控件的代码你只要一点就能进入查看 而pyqt5 pyside2 都不可以 你要看就看全部的代码 你要改你也只能 ...

  6. vue table切换 (不使用路由功能)

    背景: 一个小场景,感觉使用路由功能太浪费了,考虑用一个简单的类控制 实例代码 //v-for 实现循环<ul class="nav-bar"> <li v-fo ...

  7. Kubernetes 配置私有镜像仓库时,没有权限访问的问题

    使用 K8S 部署服务时,如果指定的镜像地址是内部镜像仓库,那么在下载镜像的时候可能会报权限错误.这是由于在 K8S 中部署服务时,K8S 需要到 Harbor 中进行一次验证,这个验证与节点中使用 ...

  8. Struts2 S2-059 (CVE-2019-0230 )复现 及流量分析、特征提取

    一.简介 2020年08月13日,Apache官方发布了Struts2远程代码执行漏洞的风险通告,该漏洞编号为CVE-2019-0230,漏洞等级:高危,漏洞评分:8.5 二.漏洞描述 Struts2 ...

  9. Tomcat 总结

    JavaWeb简介 JavaWeb,是用Java技术来解决相关web互联网领域的技术总和. Web包括:web服务器和web客户端两个部分,有两种软件架构 ​ C/S:客户端/服务器端 ​ B/S:浏 ...

  10. XML转换成TXT行数据的Java程序

    ZKe ------------------- XML数据的一个块内的所有属性,转换成TXT文件的一行.众所周知XML文件是通过类似HTML的标签进行数据的定义如图所示 属性由id, article, ...