秋招提前批专场面试官:没了解过索引的原则,回去等通知!
Posted XiaoLin__Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秋招提前批专场面试官:没了解过索引的原则,回去等通知!相关的知识,希望对你有一定的参考价值。
大家好,我是会写Bug又会Rap的XiaoLin。遇事先百度,学习关注我,今天我们为金九银十的秋招来备战——MySQL索引专题面试
🌈往期回顾
感谢阅读,希望能对你有所帮助,博文若有瑕疵请在评论区留言或在主页个人介绍中添加我私聊我,感谢每一位小伙伴不吝赐教。
为什么要使用索引
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
- 可以大大1加快数据的检索1速度(大大减少了检索的数据量),这也是创建索引最主要的原因。
- 帮助服务器避免排序和临时表。
- 将随机IO变为顺序IO。
- 可以加速表和表之间的连接,特别是实现数据的完整参考性方面特别有意义。
为什么不对表中的每一列都创建一个索引
- 当对表中的数据进行增加删除修改的时候,索引也要动态维护,这样就降低了数据的维护速度。
- 索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果是聚簇索引的话,占的空间就会更大。
- 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
使用索引的注意事项
-
要在经常搜索的列上加索引,这样可以加快搜索的速度。
-
在经常使用使用where字句的列上加索引,加快条件的判断速度。
-
要在经常排序的列上加索引,因为索引已经是排好序的,这样查询可以利用索引的排序,加快查询的时间。
-
对于中到大型表索引都是非常有效的,但是对于特大型表的话维护开销很大,不适合建立索引。
-
索引加在经常用来连接的列上,这些列主要是一些外键,可以加快连接的速度。
-
避免wher字句中对字段加函数,这样会造成索引失效,导致无法命中索引。
-
在使用InnoDB时使用与1业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。
-
将打算加索引的列设置为NOT NULL,否则将导致引擎放弃使用索引而进行全表扫描。
-
删除长期未使用的索引,不用的索引继续存在的话会造成不必要的性能损耗,mysql5.7可以通过查询
sys
库的chema_unused_indexes
视图来查询哪些索引从未被使用。
MySQL索引主要使用的两种数据结构
哈希索引
对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为1单条记录查询的时候,可以直接选择哈希索引,查询性能最快,其余大部分场景,建议选择BTree索引。
B+Tree索引
MyISAM和InnoDB实现B+Tree索引方式的区别
MyISAM
B+Tree叶子节点data域存放的 是数据记录的地址。在检索索引的时候,首先按照B+Tree搜索算法搜索索引,如果指定的key存在,则取出其data域的值,然后以data域的值为地址读取相应的数据记录,这种称为非聚簇索引。
InnoDB
其数据文件本身就是索引文件,对于MyISAM(索引文件和数据文件是分离的),InnoDB的数据文件本身就是按照B+Tree组织的一个索引结构1,树的叶节点data域保存了完整的数据记录。这个索引的的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这种称为聚簇索引(聚集索引)。
其余的索引都只是作为辅助索引,辅助索引的data域存储相应记录主键的值而不是地址。在根据主索引搜索的时候,直接找到key所在的节点即可取出数据,在根据辅助索引查找的时候,则需要先取出主键的值,再走一遍主索引。因此在设计表的时候,不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。
覆盖索引
什么是覆盖索引
如果一个索引包含了所有查询的字段的值,我们就称之为覆盖索引。在InnoDB存储引擎中,如果不是主键索引,叶子节点存储的是主键+列值,最终我们在查询的时候还是需要回表查询的,也就是说需要通过主键再查找一次,这样做会比较慢,而覆盖索引就是查出来的列和索引是一一对应的,不需要回表操作。
覆盖索引举例
我们为username、age创建了索引,我们如果执行下面的SQL语句:
select username , age from user where username = 'xiaolin' and age = 18
在查询数据库的时候,要查询的列在叶子节点都有,所以不需要回表查询。
选择索引和利用索引的原则
- 单行访问时很慢的。如果服务器从存储中1读取一个数据库只是为了获取其中的一行,那么就浪费了1很多的工作,最好读取的块中能包含尽可能多所需要的行。
- 按顺序访问范围数据是很快的。原因有两个:①顺序IO不需要多次磁盘寻道,所以比随机IO要快很多,尤其是对于机械硬盘来说。②如果服务端能够按顺序读取数据,那么就不再需要额外的排序操作,并且Group by查询也无需再做排序。
- 索引覆盖查询时很快的,如果一个索引包含了查询所需的所有列,那么存储引擎就不再需要回表查找,避免了大量的单行访问。
最左前缀原则
MySQL中的索引可以以一定的顺序引用多列,这种1索引叫做联合索引,比如user表的name和age合起来作为一个索引就是联合索引,而最左前缀的原则时指,如果查询的1时候查询条件精确匹配索引的1左边连续一列或者几列,则此索引就可以命中。
# 可以命中索引
select * from user where name = xx and age = xx ;
# 可以命中索引
select * from user where name = xx ;
# 无法命中索引
select * from user where city = xx ;
有一个需要注意的点,查询的1时候如果两个条件都用上了,但是顺序不同,比如:
select * from user where city = xx and name = xx ;
这个时候查询引擎会自动优化为匹配联合索引的顺序,索引还是可以命中的,但是不推荐这样去做,为了保险起见,还是按照索引的顺序去书写。
由于最左前缀原则,在创建联合索引时,索引字段的顺序需要考虑字段值去重后的个数,较多的放前面1,Order by字句也遵循这个规则。
避免冗余索引
冗余索引指的是索引的功能相同,能命中第一个肯定就能够命中第二个索引,比如(name,age)和name这两个索引就是冗余索引,能够命中前者的查询就必定能够命中后者,在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。
MySQL 5.7 版本后,可以通过查询 sys
库的schema_redundant_indexes
表来查看冗余索引。
索引的缺点
- 创建索引和维护索引需要耗费许多时间,当对表中的数据进行1增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低SQL的执行效率。
- 占用物理空间:索引需要使用物理文件存储,也会消耗一定的物理空间。
B树和B+树的区别
- B树的每个节点都是存储了Key和Data,Key是一条数据记录的键值,是唯一的。Data存储的是除Key以外的数据。而B+树只在叶子节点存储Data数据,这样非叶子节点就能够存储更多的Key,所以B+树相对来说更加的矮胖,因为索引树很大不能一次IO读取进入内存,树的深度浅,查找数据时IO的次数也较少,效率就更快。
- B+树的每个叶子节点都指向相邻的叶子节点,构成一个有序链表,可以按照关键码排序的次序遍历全部记录。由于数据顺序排序且相连,便于去检查找和搜索。而B树的叶子节点指针为null,则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,缓存命中性没有B+树好。
Hash索引和 B+树索引优劣分析
- Hash索引定位快:Hash索引指的就是Hash表,最大的优点就是能够在短时间内,根据Hash函数定位到数据所在的位置,这个是B+树做不到的。
- Hash冲突问题:Hash最大的问题就是Hash冲突问题了,但是对于数据库来说他还不是最主要的问题。
- Hash索引最大的问题是不支持顺序和范围查询。我们有一条SQL:
select * from user where id < 500 ;
B+树是有序的。在这种范围查询中优势1十分大,直接遍历比500小的叶子节点就够了,但是Hash索引是根据Hash算法来定位的,无法根据范围1进行查询,难除非他要把1~499的数据都进行一次hash计算定位。
索引的类型
主键索引(Primary Key)
数据库表的主键使用的就是主键索引,通常来说一张表只能有一个主键,并且主键不能为null,且不能重复。
在MySQL的InnoDB的引擎中,当没有显示的指定表的主键的时候,InnoDB会自动检查表中是否有唯一索引的字段,如果有,则选择该字段为默认的主键,如果没有,InnoDB会自动创建一个6字节的自增主键。
二级索引(辅助索引)
二级索引又称为辅助索引,因为二级索引的叶子节点存储的数据是主键,意味着通过二级索引可以确定主键的位置。
二级索引又分为唯一索引、普通索引、前缀索引等。
- 唯一索引(Unique Key):唯一索引也是一种约束,唯一索引的属性列不能出现重复的数据,但是可以允许数据为NULL,一张表允许1创建多个唯一索引。建立唯一索引的目的是为了该属性列数据的唯一性,而不是为了查询效率。
- 普通索引(Index):普通索引的唯一作用是为了快速查询数据,一张表允许创建多个普通索引,并且允许数据重复和NULL。
- 前缀索引(PreFix):前缀索引只适用于字符串类型的数据,前缀索引是对文本的前几个字符创建索引1,相比普通索引建立的数据更小,因为只取前几个字符。
- 全文索引(Full Text):全文索引1主要是为了1检索大文本数据中的1关键字信息,是目前搜索引擎数据库使用的一种技术。
聚簇索引和非聚簇索引
聚簇索引
聚簇索引即索引结构和数据放在一起的索引,主键索引属于聚簇索引。
在MySQL中,InnoDB引擎中的.ibd
文件就包含了该表的索引和数据,对于InnoDB来说。该表的索引(B+树)的每个非叶子节点存储的索引1,叶子节点存储索引和索引对应的数据。
聚簇索引的优点
聚簇索引查询的速度非常快,因为整个B+树本身就是一颗平衡多叉树,叶子节点也都是有序1的,定位到索引的节点就相当于定位到了数据。
聚簇索引的缺点
- 依赖于有序的数据:因为B+树是多路平衡树,如果索引的数据结构不是有序的,那么就需要在插入的时候排序,如果数据是整型的话就还好,如果是类似于字符串或者是UUID这种又臭又长的数据的话,插入或查找的速度肯定是比较慢的。
- 更新代价大:如果索引列的数据被修改时,那么对应的索引也会被修改,而且聚集索引的叶子节点还存放着数据,修改的代价是很大的,所以对于主键索引来说,主键一般都是不可以修改的。
非聚簇索引
非聚簇索引即索引结构和数据分开存放的索引,二级索引属于非聚簇索引,非聚簇索引的叶子节点并不一定存放数据的指针,因为二级索引的叶子节点存放的是主键,根据主键再回表查询数据。
非聚簇索引的优点
更新的代价比聚簇索引更小,非聚簇索引的更新代价就没有聚簇索引那么大了,非聚簇索引的叶子节点是不存放数据的。
非聚簇索引的缺点
- 跟聚簇索引一样,非聚簇索引也依赖于有序的数据。
- 可能会回表查询,整个是非聚簇索引最大的缺点了,当查到索引对应的指针或者是逐渐后,可能还需要根据指针或者主键再到数据库中查询。
以上是关于秋招提前批专场面试官:没了解过索引的原则,回去等通知!的主要内容,如果未能解决你的问题,请参考以下文章
秋招在即 互联网独角兽大厂提前批名单,砥砺前行冲刺大厂offer!