【转帖】MySQL索引

mysql,索引 · 浏览次数 : 0

小编点评

**索引的优点:** 1. **快速查找:**索引可以快速定位数据行的位置,从而提高搜索效率。 2. **减少搜索范围:**索引可以减少搜索范围,提高搜索速度。 3. **提高索引数据结构的利用率:**索引可以优化索引数据结构,使更多数据被索引。 4. **支持范围查询:**索引可以支持范围查询,提高查询效率。 5. **提高性能:**索引可以减少表扫描,从而提高查询性能。 **索引的类型:** 1. **主键索引:**主键索引包含表中所有主键的值。 2. **唯一索引:**唯一索引包含表中所有唯一键的值。 3. **普通索引:**普通索引包含所有非主键和唯一索引的值。 4. **组合索引:**组合索引是多个索引的结合,可以支持范围查询。 **为什么不使用二叉树索引?** 二叉树索引是一种排序的索引结构。虽然二叉树索引可以提供快速查找的性能,但当索引数据量很大时,二叉树索引可能无法保持高效性。此外,二叉树索引需要使用一些额外的存储空间来存储索引树的结构。 **索引如何查找数据?** 当使用索引查找数据时,首先从索引中找到数据行的位置。然后,从数据集中以该位置开始搜索。索引可以支持多种搜索操作,例如范围查询、子查询等。 **索引如何创建?** 索引通常会自动创建,但也可以手动创建。当创建索引时,可以指定索引类型、索引键、索引值等参数。

正文

数据表如何用索引快速查找

索引是 排好序的快速查找的数据结构

索引存储在文件系统中

索引的文件存储形式与存储引擎有关

索引数据结构:可以是二叉树、红黑树、Hash表、B-Tree、B+Tree

1、二叉树

使用索引的如下图:(如果是使用二叉树结构每一个节点都存放数据行的磁盘地址【快速定位到数据】

虽然索引不是使用的二叉树,而是使用B+Tree结构,为什么不使用二叉树呢?

如果索引是连续的数字,二叉树就会蜕变成链表,访问的速度还是和没加索引一样

这时再查找效率就变低了

2、红黑树

红黑树作为索引的数据结构呢,其实红黑树是二叉平衡树,到某个节点数值的绝对值超过2,就会重新排列(该节点不平衡),但是为什么索引还没 有选择红黑树呢,原因是树的高度比较高(一直是二叉),索引树的高度比较高,和磁盘进行IO操作比较多

3、BTree

BTree又叫多路平衡搜索树,就是一个节点开辟更大的空间,(横向)存放多个索引

  • 叶子节点具有相同的深度,叶子节点的指针为空
  • 节点中的数据从左到右递增排列

这样树的高度就解决了,横向存储更多,但是为什么不选择BTree呢,因为页节点有默认大小的,如果每个节点都存储数据data,这时页节点就存储的个数不多,这样会增加树的高度.

4、B+Tree

B+Tree对BTree做了点优化,非叶子节点不存data数据,一个节点MySQL底层叫做页节点(默认分配16KB大小)

SHOW GLOBAL STATUS like 'Innodb_page_size';
  • 1

索引一般使用int 默认是8B,指针是存储下一个页节点的地址大小为6B,所以一个页节点可以存放 16KB /(6+8)B = 1170 个 高度为3 的可以存放 = 1170 * 1170 * 16 差不多两千万多

5、MyISAM存储引擎实现

MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求

创建一个存储引擎是MyISAM的test_MyISAM表

【注意】

MySQL8开始删除了原来的frm文件,并采用 Serialized Dictionary Information (SDI), 是MySQL8.0重新设计数据词典后引入的新产物

myIsam.MYD:存储表的数据信息

myIsam.MYI:存储表的索引信息(index)

从上面的索引中可以看到,通过索引查找数据最后是定位到物理地址(MYD文件)所在的位置

比如通过where条件查询时,会判断是不是索引,如果是索引,每次查找时,把当前的页子节点从磁盘中(.MYI文件)加载到内存中【这是一个比较耗时的操作,该操作也是一次IO操作】,这也是典型的非聚集索引(索引文件和数据文件分离的

6、InnoDB存储引擎实现

InnoDB存储引擎是MySQL默认存储引擎,InnoDB存储引擎提供了具有提交、回滚、崩溃恢复能得事务安全

聚集索引:数据和索引存放在一起

InnoDB存储引擎的表必须建立主键,建立了主键,主键就是聚集索引

聚集索引查找数据的图结构如下:

创建以InnoDB存储引擎的表test_InnoDB,查看表结构

在MySQL8就只有一个.ibd文件,之前的版本是有.frm文件的

数据和索引都存放在.ibd文件中,就如上图一样,主键索引(聚集索引)自带完整的数据,普通的索引是自带id主键,再通过id主键获取数据data

如图:先定位id主键值,再回表查询(通过id值查询–》聚集索引

1)为什么建议InnoDB表必须建立主键,并且推荐使用整型自增主键?

如果不建立主键,数据库会找一个唯一区别的列作为主键,如果没找到就增加一个隐藏列rowid来维护索引(使用B+Tree),我们尽量节省MySQL的性能,不要它帮我们建立。

推荐使用整型的自增主键,因为如果使用字符串查询时是逐位比较每一位字符,比较慢

2)为什么非主键索引结构叶子节点存储的是主键值?

  • 保持一致性

当数据库表进行DML操作时,同一行记录的页地址会发生改变,因此非主键索引保存的是主键值,无需要进行改变

  • 节省存储空间

InnoDB数据本身就是汇聚到主键索引所在的B+Tree上了,如果普通索引还继续再保存一份数据,就会出现有多少索引就会存多少份数据

7、Hash

索引也是可以设定位Hash表,但是使用不多

对索引的key进行hash计算确定数据存储的位置(数组下标位置),如果出现hash冲突时,通过链地址法解决冲突

  • Hash索引无法被用来避免数据的排序操作

由于Hash索引中存放的是经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

  • 但是Hash索引仅能满足 “=” ,“in” ,不支持范围查询

由于Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的Hash算法处理之后的Hash值的大小关系,并不能保证和Hash运算前完全一样。

  • 还有Hash冲突问题,如果冲突很多维护代价很高

  • Hash索引不能利用部分索引键查询

对于组合索引,Hash索引在计算Hash值的时候是组合索引键合并后再一起计算Hash值,而不是单独计算Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash索引也无法被利用

  • Hash索引在任何时候都不能避免表扫描

Hash索引是将索引键通过Hash运算之后,将 Hash运算结果的Hash值和所对应的行指针信息存放于一个Hash表中,由于不同索引键存在相同Hash值,所以即使取满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果

  • Hash索引遇到大量Hash值相等的情况后性能并不一定就会比BTree索引高

如果创建Hash索引,那么将会存在大量记录指针信息存于同一个Hash值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

上面的两点算是不选择Hash索引的原因

通过Hash索引怎么查找数据呢???

比如使用Hash索引时,查找数据,首先计算hash值,再到链表查询数值,在定位到物理地址,才算是查找成功

哈希碰撞很多时,查询还是会变的缓慢,因为必须要遍历链表中对应的所有数据行进行匹配,同样更新索引的效率也会受到影响,导致数据的新增、修改、删除速度变慢。

既然Hash索引是不支持范围查找,那么B+Tree是怎么范围查询的呢??

8、B+Tree的范围查找

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

比如查找 范围在20-50的数据,首先查找20,之后通过20后面的指针指向后面的往后查找,直到查找到大于50的为止(通过这个叶子节点的指针可以看出,连续且自增的主键好处),使用主键自增的可以避免页节点的元素分裂导致范围查询效率低

复合索引的最左前缀优化原则

对于复合索引,它的索引B+Tree是怎么样构建的呢?

联合索引首先按照第一个字段排序,如果第一个相同再按照第二个字段排序,依次类推

9、索引分类

1、主键索引
2、唯一索引
3、普通索引(辅助索引 或者 二级索引)
4、全文索引
5、组合索引
文章知识点与官方知识档案匹配,可进一步学习相关知识
MySQL入门技能树深入索引唯一索引57859 人正在系统学习中

与【转帖】MySQL索引相似的内容:

【转帖】MySQL索引

数据表如何用索引快速查找 索引是 排好序的快速查找的数据结构 索引存储在文件系统中 索引的文件存储形式与存储引擎有关 索引数据结构:可以是二叉树、红黑树、Hash表、B-Tree、B+Tree 1、二叉树 使用索引的如下图:(如果是使用二叉树结构)每一个节点都存放数据行的磁盘地址【快速定位到数据】

[转帖]MySQL索引优化分析之性能分析(Explain执行计划)

一、MySQL常见瓶颈 二、性能分析工具Explain(执行计划 ) 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。查看官网说明: 使用: Explain + SQL语句 作用: 三、各字段解释 3.1、

[转帖]MySQL联合索引(复合索引)

Mysql联合唯一索引添加相同数据插入报错 联合索引在两个字段都存在唯一,将报错。 1.添加联合索引 alter table "表名" add unique index(`字段1`,`字段2`) 2.此时如果在插入相同的数据会报错,可以使用 no duplicate key update 解决相同数

【转帖】mysql一个索引块有多少指针_深刻理解MySQL系列之索引

索引 查找一条数据的过程 先看下InnoDB的逻辑存储结构:node 表空间:能够看作是InnoDB存储引擎逻辑结构的最高层,全部的数据都存放在表空间中。默认有个共享表空间ibdata1。若是启用innodb_file_per_table参数,须要注意每张表的表空间内存放的只是数据、索引和插入缓冲B

【转帖】《MySQL高级篇》四、索引的存储结构

1. 为什么使用索引 假如给数据使用 二叉树 这样的数据结构进行存储,如下图所示 2、索引及其优缺点 2.1 索引概述 2.2 优点 类似大学图书馆建书目索引,提高数据检索的效率,降低 数据库的 IO 成本 这也是创建索引的主要的原因。通过创建唯一索引,可以保证数据库表中每一行 数据的唯一性 (唯一

[转帖]MySQL创建联合索引报key长度超3072 bytes的[42000][1071]错误

问题时这样的,我在建表时加了联合索引结果报key长度超过3072个字节了,如下图。 [42000][1071] Specified key was too long; max key length is 3072 bytes 先说解决方案:1.调整索引字段,包括修改字段长度、更换字段;2.使用前缀索

【转帖】查看mysql库大小,表大小,索引大小

https://www.cnblogs.com/lukcyjane/p/3849354.html 说明: 通过MySQL的 information_schema 数据库,可查询数据库中每个表占用的空间、表记录的行数;该库中有一个 TABLES 表,这个表主要字段分别是: TABLE_SCHEMA :

[转帖]深入理解mysql-第六章 mysql存储引擎InnoDB的索引-B+树索引

一、引入索引 在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,因为要遍历所有的数据页,时间复杂度就是O(n),所以这种方式显然是超级耗时的。所以我们需要采取一定的数据结构来存储数据,方便我们进行数据的增删改

[转帖]MySQL提升笔记(4)InnoDB存储结构

https://cdn.modb.pro/u/310923 这一节本来计划开始索引的学习,但是在InnoDB存储引擎的索引里,存在一些数据存储结构的概念,这一节先了解一下InnodDB的逻辑存储结构,为索引的学习打好基础。 从InnoDB存储引擎的存储结构看,所有数据都被逻辑地放在一个空间中,称之为

[转帖]【MySQL 8】MySQL 5.7都即将停只维护了,是时候学习一波MySQL 8了

https://www.cnblogs.com/paul8339/p/17026571.html 阅读目录 账户与安全 索引增强 原子DDL操作 通用表达式(CTE) 其他 MySQL 8新特性选择MySQL 8的背景:MySQL 5.6已经停止版本更新了,对于 MySQL 5.7 版本,其将于 2