首页 > 编程知识 正文

数据库索引种类以及特点区别,数据库索引类型和区别

时间:2023-05-05 19:26:04 阅读:190064 作者:2297

索引包括主键索引、唯一索引、普通索引、聚合索引和全文索引,但索引实际上是在无序数据上创建索引。 每个查询都可以根据索引快速找到我们想要的数据(如词典目录a-z )。

优点

提高数据检索速度提高group by、order by的分组和排序时间缺点

每次增加数据时都需要更新索引。 随着数据量的增加,索引的维护成本也会增加,并占用一定的存储空间。 myi后缀的文件保存索引文件。 索引类型主键索引数据列可以作为禁止重复、禁止为空或外键引用,并且一个表中只能有一个主键索引

唯一的索引数据列不能重复。 允许空值,不能作为外键引用。 此外,可以在一个表中为多个列创建唯一的索引

普通索引的基本索引类型。 没有唯一性限制,允许空值,并且不作为外键引用。 一个表可以有多个常规索引

主键索引、唯一索引、 普通索引差异:索引类型是否允许重复数据是否允许空值作为外键索引的数量是否限制主键索引是否只允许一个唯一索引否是否允许多个普通索引

聚合索引(聚簇索引)在聚合索引中,表中数据行的物理位置与逻辑值(索引和数据相同的文件)的顺序相同,并且一个表只能包含一个聚合索引。 因为物理顺序只有一个。 聚合索引通常提供更快的数据访问。

这里,InnoDB采用簇索引,数据和索引文件是一个idb文件,表数据文件自身是主索引,相邻的索引接近存储器。 叶节点data域保存着完整的数据记录。 数据[非主键id列data]主键索引[索引key:表主键id] )。 叶节点直接存储数据记录,以主键id为密钥,叶节点直接存储数据记录。 (底层存储结构: frm -表定义,ibd: innoDB数据索引文件)

)1)如果表定义了主键,则PK是聚合索引;

)2)如果表没有定义主键,则第一个not NULL unique列是聚合索引。

(3)否则,InnoDB将隐藏的row-id制作为集合索引

非聚簇索引和数据分离的索引。

其中,MyISAM的基础是采用非簇索引,使用myi索引文件和myd数据文件的分离,索引文件仅存储数据记录的指针地址。 叶节点data域存储指向数据记录的指针地址。 (底层存储结构: frm -表定义、myi -myisam索引、myd-myisam数据)

覆盖索引的索引意味着索引包含查询中的所有字段,在这种情况下不需要返回表查询

在MySQL中,只有B-Tree索引可以用作覆盖索引。因为哈希索引等都不存储索引的列的值,覆盖索引对MyISAM和InnoDB都非常有效,可以缩短系统调用和数据复制等时间

要对索引进行分组,请使用多列创建一个索引。 例如,B-Tree方法

全文索引主要用于检索大量数据。 例如,您可以在淘宝或京东商品搜索中创建全文索引。 (用like做不到模糊匹配吧。 )此类型在mysql5.6中开始与InnoDB引擎的全文索引相对应。 功能没有solr和es等专业的搜索引擎,只要需求简单就可以使用全文索引

应用场景:适用于海量数据的关键词模糊搜索,如简易版搜索引擎

如何实现索引B-Tree索引InnoDB使用B-Tree算法。 这意味着每个叶节点都包含指向下一个叶节点的指针,如树中所示

适用场景:最常见的索引类型,可应用于各种场景

工作原理: B-Tree索引根据第一个索引列对合并索引中的索引项进行排序,如果第一个索引列相同,则根据第二个索引列进行排序。

如果适用于B-Tree索引:

全值匹配:搜索条件是匹配索引中所有列的最左前缀。 搜索条件是只有索引中的第一列匹配的列前缀。 例如,有姓和名两个索引,首先找到张栏,然后根据找到的栏找到以s开头的人。 也可以应用于索引匹配范围的值。 例如,你也可以找一个姓在陈和张之间的人。 或者,姓张,名字在san到si范围内的人只能访问索引的查询。 这意味着,如果要查询的所有数据都包含在索引中,则只需要访问该索引,而不需要访问数据行。 例如,只需查询姓和名这两列,这两列正好是联合索引。 这样的索引称为覆盖索引的索引排序。 例如,如果按姓排序,则不能用于B-Tree索引:

在最左列开始搜索之前,索引不可用。 例如,如果直接搜索名为san的人,则不适用于索引索引不完整。 例如,如果有三个字段的串联索引,条件中只有第一个和第三个字段条件,并且跳过了中间的列,则只能使用到索引中的第一列。 如果查询中包含列范围查询,则该列右侧的所有列都不能使用索引优化查询。 (范围时,没有具体的值。

如果散列索引已被索引到列,则存储引擎将从所有索引列中为每行中的数据计算散列代码。 每行计算的哈希代码构成哈希表,同时在哈希表中存储指向每个数据行的指针。

散列表的结构如下

仅适用场景:等

值匹配且数据重复率低且对索引查找速度要求高的情况

可以应用到哈希索引的情况:

只有精确匹配全部索引行的查询条件才能利用索引

无法使用到哈希索引的情况:

索引中不包含任何列的值索引无法应用于排序不支持部分索引列匹配查找(必须使用全部索引列的查询条件才能使用哈希索引优化查询)无法范围查找,只能等值比较哈希冲突会影响性能:比如某个列的数据重复率非常高,则每次在找到匹配的哈希后还需要对这个哈希码的所有数据进行等值比较

其中,还有一个叫做“自适应哈希索引”,是当InnoDB注意到某些索引的使用频率很高时,会在B-Tree索引之上再建立一层哈希索引,以提高查询效率

空间数据索引(R-Tree)

空间索引可用于地理数据存储,它需要GIS相关函数的支持,由于MySQL的GIS支持并不完
善,所以该索引方式在MySQL中很少有人使用。

扩展 什么是回表

如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表

比如如下例子,先使用普通索引查询除出ID,然后再去聚簇索引查询具体数据的过程就叫左做回表

如何避免回表?

使用聚集索引(主键或第一个唯一索引)就不会回表,普通索引就会回表

比如select id, name, sex from user;,将单列索引(name)升级为联合索引(name, sex),即可避免回表,因为要查询的name和sex都在索引中了

索引下推

MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数

select * from tuser where name like '张 %' and age=10 and ismale=1;

没有索引下推:首先根据索引来查找记录,然后再根据where条件来过滤记录(回表)
有索引下推:MySQL会在取出索引的同时,判断是否可以进行where条件过滤再进行索引查询(回表)

唯一索引导致死锁

如图所示,有三个事务同时插入同一个记录,导致唯一索引冲突的过程:

死锁发生过程:

T1时刻sessionA插入会加排他锁T2时刻SessionB插入同id会主键冲突,会加上共享锁T3时刻SessionC插入同id会主键冲突,会加上共享锁这时,SessionA回滚释放排他锁,sessionB向获得排他锁,但发现sessionC有共享锁存在,B和C相互等待造成死锁

根本原因:
唯一索引导致,本质是并发请求导致一个数据重复插入或是网络抖动造成

解决方案:

可以使用缓存将重复请求去重,确保同时只执行一个相同sql异常捕捉,mysql有死锁检测和恢复,只有一个事务会成功,只需要catch异常即可

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。