索引
1、什么是索引
索引其实是一种数据结构,能够帮助我们快速的检索数据库中的数据
2、索引具体采用的哪种数据结构呢
常见的MySQL主要有两种结构:Hash索引和B+ Tree索引,我们使用的是InnoDB引擎,默认的是B+树
3、采用B+ 树吗?这和Hash索引比较起来有什么优缺点吗
Hash索引底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储关系上是完全没有任何顺序关系的,所以,对于区间查询是无法直接通过索引查询的,就需要全表扫描。所以,哈希索引只适用于等值查询的场景。而B+ 树是一种多路平衡查询树,所以他的节点是天然有序的(左子节点小于父节点、父节点小于右子节点),所以对于范围查询的时候不需要做全表扫描
4、面这个范围查询的,你还能说出其他的一些区别吗
-
哈希索引适合等值查询,但是无法进行范围查询
-
哈希索引没办法利用索引完成排序
-
哈希索引不支持多列联合索引的最左匹配规则
-
如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞问题
5、B+ Tree的叶子节点都可以存哪些东西吗
InnoDB的B+ Tree可能存储的是整行数据,也有可能是主键的值
6、那这两者有什么区别吗
索引B+ Tree的叶子节点存储了整行数据的是主键索引,也被称之为聚集索引。而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚集索引
7、那么,聚集索引和非聚集索引,在查询数据的时候有区别吗
因为主键索引树的叶子节点直接就是我们要查询的整行数据了。而非主键索引的叶子节点是主键的值,查到主键的值以后,还需要再通过主键的值再进行一次查询简称回表
8、回表查询是否一定会查询多次
不会,可以通过覆盖索引来实现一次查询
9、什么是覆盖索引
一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取
方式一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引,当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息
10、创建索引的时候都会考虑哪些因素呢
我们一般对于查询概率比较高,经常作为where条件的字段设置索引
11、需要做联合索引多个字段之间顺序你们是如何选择的呢
把识别度最高的字段放到最前面,MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配
12、索引下推、查询优化
索引下推实在mysql5.6版本进行跟新的默认开启,使用SET optimizer_switch = 'index_condition_pushdown=off';可以将其关闭,举例:
people表中(zipcode,lastname,firstname)构成一个索引
SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';
未使用索引下推:MySQL会通过zipcode='95054'从存储引擎中查询对应的数据,返回到MySQL服务端,然后MySQL服务端基于lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断数据是否符合条件。
使用索引下推:MYSQL首先会返回符合zipcode='95054'的索引,然后根据lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断索引是否符合条件。如果符合条件,则根据该索引来定位对应的数据,如果不符合,则直接reject掉。有了索引下推优化,可以在有like条件查询的情况下,减少回表次数。
13、索引是否生效排查手段
可以通过explain查看sql语句的执行计划,通过执行计划来分析索引使用情况
14、什么情况下会发生明明创建了索引,但是执行的时候并没有通过索引呢
此问题考查查询优化器:
一条SQL语句的查询,可以有不同的执行方案,至于最终选择哪种方案,需要通过优化器进行选择,选择执行成本最低的方案
- 根据搜索条件,找出所有可能使用的索引
- 计算全表扫描的代价
- 计算使用不同索引执行查询的代价
- 对比各种执行方案的代价,找出成本最低的那一个