后端程序员必看的MySQL索引面试知识点

原创做者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。程序员

与数据库索引有关的知识,说实在的,真的是很复杂,原本想好好看看这方面的东西,而后写篇文章详细谈谈的,后来发现索引的知识太难太深,要谈得全面又详细真的很难,因此最后仍是把本身学到的和想到的变成下面一个个的问题,但愿能对你们帮助!数据库

知识点

问题1:什么是数据库索引?

数据库索引是数据库系统中一个重要的概念,索引也叫作key,是一种用于提高数据库查询效率的数据结构,咱们能够把索引理解成一本书的目录,经过目录咱们能够快速找到对应章节的内容,一样的,经过数据库索引,咱们能够快速找到数据表中对应的记录。bash

总而言之,索引就像给数据表建了一个目录同样。数据结构

问题2:为何在使用索引?

1 . 使用索引大大减小了存储引擎须要扫描的数据量,若是没有使用索引的话,每查询一行数据都要对数据表进行扫描,这样的话会很是慢。性能

2 . 因为索引已经排好序的,因此对数据表进行ORDER BYGROUP BY等操做时,能够很快获得结果。ui

3 . 索引能够将随机的I/O转为顺序的I/O,避免高昂的磁盘IO成本,提高查询效率。spa

问题3:MySQL索引在哪一个模块中实现的?

MySQL的索引是在存储引擎这一层实现的,所以每一种存储引擎都有不一样的实现方式,对同一种索引的处理方式也完成不一样。指针

问题4:为何设置了索引却不起做用?

若是使用以%开头的LIKE语句进行模糊匹配,则没法使用索引,如:code

SELECT * FROM users WHERE name LIKE '%小张%';

SELECT * FROM users WHERE name LIKE '%小张';
复制代码

不过以%为结尾则可使用索引,如:cdn

SELECT * FROM users WHERE name LIKE '张%';
复制代码

OR语句先后没有同时使用索引,好比下面的语句,字段id有索引,而字段name没有建立索引,那么下面的语句只能全表扫描,没法用到索引:

SELECT * FROM users id = 10 or name='test'
复制代码

问题5:MySQL索引底层使用什么数据结构?

MySQL中,大部分状况下,索引都是使用B-Tree做为底层数据结构,B-Tree只是一种泛称,实际上不一样的存储引擎使用B-Tree时,有不一样的变种,好比InnoDB使用的是B+Tree

另外也有一些特殊的索引结构,好比哈希索引,哈希索引底层则使用的是哈希表,在MySQL中,只有Memory存储引擎支持哈希索引。

问题6:什么状况下数据表不适合建立索引?

1 . 对于用于存储归档历史数据的且不多用于查询的数据表,不建议建立索引。

2 . 数据量比较小的数据表,并且将来数据也不会有太大增加的数据,不该该建索引,好比用于保存配置的数据表。

3 . 修改频繁,且修改性能远大于查询性能时,不该该再建立索引。

问题7:什么是回表?

回表是对Innodb存储引擎而言的,在InnoDB存储引擎中,主键索引的叶子节点存储的记录的数据,而普通索引的叶子节点存储的主键索引的地点。

当咱们经过主键查询时,只须要搜索主键索引的搜索树,直接能够获得记录的数据。

当咱们经过普通索引进行查询时,经过搜索普通索引的搜索树获得主键的地址以后,还要再使用该主键对主键搜索树进行搜索,这个过程称为回表。

问题8:聚簇索引与非聚簇索引的区别?

聚簇索引:聚簇索引的顺序就是数据的物理存储顺序,而且索引与数据放在一块,经过索引能够直接获取数据,一个数据表中仅有一个聚簇索引。

非聚簇索引:索引顺序与数据物理排列顺序无关,索引文件与数据是分开存放。

问题9:MySQL主键索引、惟一索引与普通索引的区别?

设置为主键索引的字段不容许为NULL,并且一张数据表只能有一个主键索引。

设置为惟一索引的字段,其字段值不容许重要。

普通索引能够包含重复的值,也能够为NULL

问题10:索引能够提升查询性能,那是否是索引建立越多越好?

索引做为一个数据表的目录,自己的存储就须要消耗不少的磁盘和内存存储空间。

并助在写入数据表数据时,每次都须要更新索引,因此索引越多,写入就越慢。

尤为是糟糕的索引,建得越多对数据库的性能影响越大。

问题11:MyISAM与InnoDB在处理索引上有什么不一样?

MyISAM存储引擎是非聚族索引,索引与数据是分开存储的,索引文件中记录了数据的指针

InnoDB存储引擎是聚族索引,即索引跟数据是放在一块的,InnoDB通常将主键与数据放在一块,若是没有主键,则将unique key做为主键,若是没有unique key,则自动建立一个rowid做为主键,其余二级索引叶子指针存储的是主键的位置。

问题12:什么是索引的最左前缀原则?

MySQL数据库不单能够为单个数据列建立索引,也能够为多个数据列建立一个联合索引,好比:

CREATE TABLE test(
    a INT NOT NOT,
    b INT NOT NOT,
    KEY(a,b)
);
复制代码

当咱们使用下面的查询语句时,因为WHERE语句中查询的条件就是联合索引,因此能够很快查询到数据。

SELECT * FROM test WHERE a=1 AND b=1; 
复制代码

一样,下面的语句也会利用上面建立的联合索引,这是由于MySQL会按照索引建立的顺序进行排序,而后根据查询条件从索引最左边开始检测查询条件是否知足该索引,因为字段a在最左边,因此知足索引。

SELECT * FROM test WHERE a=1; 
复制代码

而使用字段b进行查询时,则为知足,由于从最左边匹配到的是字段a,因此MySQL判断为不知足索引条件。

SELECT * FROM test WHERE b=1; 
复制代码

从上面例子能够很好地了解索引的最左前缀原则,同时也说明了索引顺序的重要性。

问题13:什么是覆盖索引?

若是一个索引中包含查询所要的字段时,此时不须要再回表查询,咱们就称该索引为覆盖索引。

好比下面的查询中,字段id是主键索引,因此能够直接返回索引的值,显著提高了查询的性能。

SELECT id FROM users WHERE id BETWEEN 10 AND 20;
复制代码

小结

固然,上面列出的只是索引的一小部分知识点,有什么回答不对的地方,欢迎指出。


若是你以为文章不错,欢迎扫码关注,你的关注就是我写做的最大动力

相关文章
相关标签/搜索