什么是索引?
索引是一种用于快速查询和检索数据的一种数据结构,常见的索引结构有:B树,B+树,Hash 索引等
对于 Mysql 来说,支持和不支持与使用的存储引擎有关,Innodb 支持了 Hash 索引,但又没有完全支持,因为 InnoDB 不允许用户手动创建 Hash 索引,但是 InnoDB 的自调优会自己建立合适的 Hash 索引
通俗的来说,索引就是一本书的目录,当我们需要找实际内容的时候,先去看一下目录,目录上写了实际内容的页码,我们可以马上翻到对应的页
在这里分享一个xiao ji si,InnoDB 表最多可以包含 1017列,最多创建 64个 二级索引
索引的类型
主键索引:
数据表的主键列使用的就是主键索引
二级索引:
二级索引又称为辅助索引,是因为二级索引的叶子节点存储的数据是主键。也就是说,通过二级索引,可以定位主键的位置
- **普通索引:**最常用的索引,唯一的作用就是加快检索速度
- **唯一索引:**唯一索引的属性列不能出现重复数据,但允许为null,常用来约束列的唯一性
- **前缀索引:**前缀索引只能用于字符串类型的数据,对文本的前几个字建立索引,相比于普通索引建立的数据更小
- **全文索引:**全文索引用于检索大文本中的关键信息,5.6以后 InnoDB支持了全文索引
聚集索引与非聚集索引有什么区别?
聚集索引:即索引结构和数据存放在一起的索引
可以想象一下,我们打开书的目录,定位到我们要找到索引时,发现内容就在索引下
聚集索引的速度非常快,因为整个 B+树就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点就意味着定位到了数据
聚集索引的缺点:
- 依赖于有序数据:首先聚集索引依赖有序的数据,因为整个 B+树就是一颗多叉平衡树,如果数据不是有序的,在插入时就要排序,对于字符串或者UUID这种又长又难比较的数据,插入或查找的速度肯定比较慢
- 更新代价大:如果对索引列的数据修改时,那么对应的索引也将会被修改,况且聚集索引的叶子节点中还存放着数据,修改的代价肯定是比较大的
非聚集索引:即索引结构和数据存分开存放的索引
首先更新代价比聚集索引要小 ,非聚集索引的更新代价就没有聚集索引那么大了,非聚集索引的叶子节点是不存放数据的
非聚集索引的缺点:
- 依赖于数据的有序性
- 可能会二次回表查询:当我们翻开书页目录,找到索引,然后再翻开对应的页数去找内容的,就是二次回表了
可能会二次回表?
假设我们准备使用SQL查询字段 name、age、address, 而刚好就建立了一个联合索引 idx_name_age_address,那么查到索引就相当于找到了数据,直接返回就可以了,这种情况用不着二次回表,也称为覆盖索引
select name, age, addresss from table where name = 'xxx'
索引的数据结构
Hash 索引
哈希表是键值对的集合,通过键(key)即可快速取出对应的值(value),因此哈希表可以快速检索数据**(接近 O(1))**
为何能够通过 key 快速取出 value呢? 原因在于 哈希算法(也叫散列算法)。通过哈希算法,我们可以快速找到 value 对应的 index,找到了 index 也就找到了对应的 value
Hash 精确查找非常的快,但是 Hash 索引也有一些缺点:
- Hash 冲突的问题,不同的 Key 通过散列算法得出了一样的 Index,我们通常的解决办法是链地址法
- Hash 索引不支持顺序和范围查找
BTree 和 B+Tree
B 树全称为 多路平衡查找树 ,B+ 树是 B 树的一种变体。B 树和 B+树中的 B 是 Balanced (平衡)的意思
B 树& B+树两者有何异同呢?
- B 树的所有节点既存放键(key) 也存放 数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
- B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。
- B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。