MYSQL索引底层原理

1. 索引的本质

索引是帮助MYSQL高效获取数据的排好序的数据结构。

索引一般以文件形式存储在磁盘上。

2. 按索引的分类

2.1. 按字段约束分类

2.1.1. 普通索引

是最基本的索引,它没有任何限制。

ALTER TABLE 'table_name' ADD INDEX index_name('col');

CREATE INDEX index_name ON table_name('col');

2.1.2. 主键索引(PRIMARY)

即主索引,是一种特殊的唯一索引,根据主键建立,一个表只能有一个主键索引,不允许重复,不允许有空值。

ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');

2.1.3. 唯一索引(UNIQUE)

用来建立索引的列的值必须是唯一的,允许空值。如果是组合索引,则列值的组合必须唯一。

ALTER TABLE 'table_name' ADD UNIQUE INDEX index_name('col');

2.1.4. 全文索引(FULLTEXT)

主要用来查找文本中的关键字,而不是直接与索引中的值相比较。全文索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的参数匹配。

用于char、varchar、text列上。对于文本的大对象,或者较大的char或vachar类型的数据,如果用普通索引,那么匹配文本中间的单词,如果用like需要很长的时间来处理,相应时间会大大增加。这种情况,就可使用全文索引,在生成全文索引时,会为文本生成一份单词的清单,在索引时会根据这个单词清单来索引。

在数据量较大时,先将数据插入表中,再给表创建全文索引,要比先建一个有全文索引的表,再插入数据的速度快很多。

全文索引配合match against操作使用,而不是用like语句。

ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');

SELECT * FROM table_name WHERE MATCH (列名) AGAINST ('查询字符串' IN NATURAL LANGUAGE MODE);

2.1.5. 组合索引

用多个列组合构建的索引,遵循“最左前缀原则”,把最常用作为检索或排序的列放在最左边,依次递减。其效率大于索引合并。

ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

在使用组合索引的时候可能因为列名长度过长而导致索引的key太大,导致效率降低,在允许的情况下,可以只取列的前几个字符作为索引。

ALTER TABLE 'table_name' ADD INDEX index_name(col1(4), col2(3));

2.2. 按索引与数据的存储关联性分类

2.2.1. 聚簇索引

Innodb中的主键索引(B+树索引)结构中,非叶子节点存储的是索引指针,叶子节点存储的是既有索引也有整行数据。索引和数据是存储在一起的,是典型的聚簇索引。

2.2.2. 非聚簇索引

InnoDB中的辅助索引结构,叶子节点存储的是主键索引值,并没有完整数据,所以为非聚簇索引。

MyISAM中索引和数据文件分开存储,B+Tree的叶子节点存储的是数据存放的地址,而不是具体的数据,是典型的非聚簇索引;换言之,数据可以在磁盘上随便找地方存,索引也可以在磁盘上随便找地方存,只要叶子节点记录对了数据存放地址就行。因此,索引存储顺序和数据存储关系毫无关联,是典型的非聚簇索引。

3. 索引数据结构

3.1. 数据结构网站

        数据结构网站

3.2. 二叉树

二叉树是指树中节点的叶子不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。

缺点:递增的列(如:id),单边增长数据列,退化成了链表结构。

3.3. 红黑树

红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于AVL 。

当两边层数相差大了,会自动平衡,保证两边层数不要相差过多。

缺点:大数据量时,树的层数过高,导致查询效率低。

3.4. Hash表

Hash表也叫散列表,是根据关键码值直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。精确查找很快。

缺点:

1> 利用hash存储的话需要将所有的数据文件添加到内存,比较耗费内存空间。

2> 无法支持范围查找,无法支持排序,以及无法支持部分模糊查询。

3> 不支持多列联合索引。

4> 如果Hash碰撞过多,也会成链表结构,索引效率会降低。

3.5. B-Tree

B树是一种自平衡的树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。

特点:

1>叶节点具有相同的深度,叶节点的指针为空。

2>所有索引元素不重复;

3>节点中的数据索引从左到右递增排列。

4>每个节点都有data。

缺点:

1>如果data过大,一个节点存放的数据少,这样会导致树加深,这样也增加了IO次数。

2>范围查询支持不好。

3.6. B+Tree

B+树是B树的一种变形形式,B+树上的叶子结点存储关键字以及相应记录或记录的地址,叶子结点以上各层作为索引使用。

B+树的查找与B树不同,当索引部分某个结点的关键字与所查的关键字相等时,并不停止查找,应继续沿着这个关键字右边的指针向下,一直查到该关键字所在的叶子结点为止。

特点:

1>非叶子节点不存储data,只存储索引,可以放更多的索引。

2>叶子节点包含所有索引字段。

3>叶子节点用指针连接,提高区间访问的性能。

优点:

1>较B-Tree,横向存储的索引更多,这样可大量减少磁盘I/O的次数。

2>能很好的支持范围查询,因为叶子节点之间有双向指针连接。

4. 预备知识

4.1. 局部性原理

局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。

当一个数据被用到时,其附近的数据也通常会马上被使用。

4.2. 磁盘预读原理

由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。

由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。

预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存 储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统 会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中。

4.3. 数据页

数据页是mysql中磁盘和内存交换的基本单位,也是mysql管理存储空间的基本单位。

同一个数据库实例的所有表空间都有相同的页大小;默认情况下,表空间中的页大小都为 16KB,当然也可以通过改变 innodb_page_size 选项对默认大小进行修改,一般都是操作系统的整数倍。

一次最少从磁盘读取16KB内容到内存中,一次最少把内存中16KB内容刷新到磁盘中。

名称

中文名

占用空间大小

简单描述

File Header

文件头部

38字节

页的一些通用信息

Page Header

页面头部

56字节

数据页专有的一些信息

Infimum + Supremum

最小记录和最大记录

26字节

两个虚拟的行记录

User Records

用户记录

大小不确定

实际存储的行记录内容

Free Space

空闲空间

大小不确定

页中尚未使用的空间

Page Directory

页面目录

大小不确定

页中的某些记录的相对位置

File Trailer

文件尾部

8字节

检验页是否完整

5. InnoDB的索引实现

InnoDB的主键索引是聚簇索引,叶子节点包含了完整的数据记录,数据和索引在一起,存放在同一个文件中(XXX.ibd)。

一张表有且仅有一个聚簇索引。

InnoDB的非主键索引是非聚簇索引,叶子节点没有数据记录。

5.1. 主键索引

如果一张表没有主键,mysql会找一列unique索引作为聚簇索引来组织数据。如果没有这样的索引,mysql会生成一个唯一的隐藏列,类似于rowid,用这个列生成聚簇索引,从而组织数据。

主键列推荐用自增整型,这样生成树的时候,直接往后添加,不需要调整排序;而且越小越好,这样一页放的数据量更多,查询更快。整型查询比较大小时,速度更快。

一页存放的主键个数:16kb/(8+6)byte=1170个,其中假设主键是bigint占8byte,指针占6byte

叶子节点存放的数据条数:16kb/1kb=16行数据,其他假设一行数据占1kb,一页可存16行数据

B+树层数为2可存的数据条数:1170*16=18720

B+树层数为3可存的数据条数:1170*1170*16=21902400(2千万条数据)

5.2. 非主键索引

非主键索引,也可以叫二级索引、辅助索引,它属于非聚簇索引,即索引和数据是分开存放的。

InnoDB的非主键索引的叶子节点没有存储整行数据,而是存储的主键值,这样既能保证数据一致,也能节省存储空间。

这样的设计,导致的一个问题是,当查询用到了非主键索引,查到主键之后,还需要通过主键到主键索引中做回表查询,从而得到数据。所以并不是所有情况都会走这个非主键索引,如果回表次数过多,则会放弃使用该索引,直接进行全表扫描。

6. MyISAM的索引实现

6.1. MyISAM的索引

MyISAM引擎同InnoDB一样,也是使用B+Tree作为索引的数据结构,不同的是MyISAM索引的叶节点data域中存放的是数据记录的地址。MyISAM的索引方式叫做“非聚簇索引”。

因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。

6.1.1. 主键索引

MyISAM可以没有主键索引。

6.1.2. 非主键索引

在MyISAM中,主键索引和非主键索引在结构上没有任何区别,只是主键索引要求key是唯一的,而非主键索引的key是可以重复的。

MYSQL索引底层原理相关推荐

  1. 深入理解 MySQL 索引底层原理

    hi ,大家好,今天分享MySQL硬核知识,希望大家可以学习到真正的知识,慢慢积累,厚积薄发: 看完本文可以学到什么  一步一步推导出 Mysql 索引的底层数据结构  怎么分析回答技术选型问题 一步 ...

  2. Mysql 索引底层原理

    一步一步推导出 Mysql 索引的底层数据结构. Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 My ...

  3. MySQL索引底层原理理解以及常见问题总结

    目录 二叉查找树为索引 红黑树为索引 B树作为索引 B+树作为索引 MyISAM存储引擎索引实现 InnoDB存储引擎索引实现 常见问题 聚集索引与非聚集索引 InnoDB基于主键索引和普通索引的查询 ...

  4. MySQL 索引底层原理详解

    大家好 我是积极向上的湘锅锅

  5. mysql 取第一条_MySQL索引底层(一)索引底层原理

    微信公众号:Java患者 专注Java领域技术分享 MySQL索引底层原理 局部性与页 在操作系统中,我们执行一个指令去磁盘取数据,那么他会从磁盘取出4KB数据,这个4KB就是一个局部单位,而这4KB ...

  6. mysql 字符串 底层_Mysql 的索引底层原理及数据结构详解

    Mysql 的索引底层原理 1.什么是索引? 索引是一种排好序的数据结构,mysql目前默认使用的是b+树. 2.为什么使用b+树? 例如表table 数据 id name 1 zs 2 ls 3 s ...

  7. MySQL索引底层实现原理 MyISAM非聚簇索引 vs. InnoDB聚簇索引

    MySQL索引底层实现原理 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的 ...

  8. 面试官:MySQL索引底层数据结构原理与性能调优,你能回答多少?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新,可以微信搜索[小奇JAVA面试]第一时间阅 ...

  9. 【MySQL】InnoDB行格式、数据页结构以及索引底层原理分析

    目录 一.MySQL架构图 二.InnoDB数据页结构 2.1 局部性原理 2.2 InnoDB的数据页格式 三.InnoDB的行格式 3.1 Compact行格式 3.1.1 变长字段长度列表 3. ...

最新文章

  1. 命名实体识别视频51cto
  2. 《图解HTTP》笔记之TCP/IP
  3. 基于OpenCV的图像梯度与边缘检测!
  4. 一位人工智能总监对AI行业的【实话实说】
  5. Java小工具:TimingTools
  6. Linux驱动程序中的file,inode,file_operations三大结构体
  7. rabbitmq-5-案例1-简单的案例
  8. 初级爬虫师_初级设计师的4条视觉原则
  9. Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh
  10. 基于视觉的烟雾/火焰检测数据集整理(检测、识别、分割)
  11. Spark MLlib中的协同过滤
  12. ubuntu18的网关ip在哪里配_技术|如何在 Ubuntu 18.04 LTS 中配置 IP 地址
  13. 电脑上怎么做pdf文件_怎么编辑pdf文件内容?什么工具可以编辑pdf?
  14. Python——eventlet.wsgi
  15. ExtendSim高效 易学 易用 真正能用起来的系统仿真与优化工具
  16. UnityShader[3]屏幕后处理学习笔记
  17. winpe装双系统linux_如何安装linux,winpe下如何安装linux的ISO
  18. 【多模态】《Visual7W: Grounded Question Answering in Images》论文阅读笔记
  19. 论文专利博客写作总结
  20. 戴尔3080计算机重装系统步骤,戴尔OptiPlex 3080MT台式机重装系统BIOS设置教程

热门文章

  1. html编辑器自定义脚本,我的自定义MAX脚本编辑器,代码高亮功能
  2. QQ、MSN、淘包旺旺、Skype常设对话的html链接代码
  3. VQA4-2017-Hierarchical Question Image Co-Attention for VQA
  4. Unity3d入门选作作业(一)
  5. SQL是什么?SQL能做什么?
  6. 可编程的SQL是什么样的?
  7. linux redhat中文字体安装,中文Linuxredhat中文字体安装
  8. 上传大文件解决方案插件
  9. ROS学习笔记74(TF Using Stamped datatypes with tf::MessageFilter)
  10. CodeForces刷题:Theatre Square、Watermelon、Chat Server‘s Outgoing Traffic、Triangle、Die Roll