MySQL索引

参考博文:MySQL索引——阿里面试

1.索引模型、索引概念

当数据库业务量增加时,每天数据达到百万级的数据量时,有了以下对话。

面试官:你们每天这么大的数据量,都是保存在关系型数据库中吗?

回答:是的,线上使用的MySQL数据库。

面试官:每天百万级数据,一个月千万级的数据量了,是否有对数据库查询做一些优化?

回答:我们是对数据库中建立了索引。

一般技术能力比较强的面试官,会采用层层递进的方式,将问题由浅入深,从理论到实践,这是比较考验个人的能力的。

面试官:那你能说说什么是索引吗?

回答:索引是一种数据结构,能够帮助我们快速检索数据库中的数据。

面试官:那么索引采用的是哪一种数据结构呢?

回答:常见的MySQL主要有两种数据结构:Hash索引和B+ Tree索引,我们使用的是InnoDB引擎,默认的是B+树。

面试官:既然你提到了InnoDB使用B+ Tree的索引模型,那么你知道为什么采用B+ 树吗?这和Hash索引比较起来有什么优缺点呢?

回答:因为Hash索引底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储关系上是没有任何顺序关系的,所以,通过区间查询是无法直接通过索引查询的,就需要全表扫描,所以,哈希索引只适用于等值查询的场景。而B+ Tree是一种多路平衡查询树,所以它的结点是天然有序的(左子结点小于父节点,父节点小于右子结点),所以对范围查询的时候不需要用全表扫描。

面试官:除了上面范围查询的场景,你还能说出其它的一些差别吗?

回答:B+ Tree和Hash索引区别  Hash索引适合等值查询,但是没法完成范围查询,哈希索引没有办法利用索引完成排序,哈希索引不支持多列联合索引的最左匹配规则,如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞问题。

 

2.聚簇索引、覆盖索引

面试官:刚刚聊到B+ Tree,那你知道B+ Tree的子节点都可以存放那些东西吗?

回答:InnoDB的B+ Tree可能存储的是整行数据,也有可能是主键的值。

面试官:那这两者有什么区别吗?

回答:在InnoDB里,索引B+ Tree的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引B+ Tree的叶子结点存储了主键的值是非主键索引,也被称之为非聚簇索引。

面试官:聚簇索引和非聚簇索引在查询数据时有区别吗?

回答:聚簇索引查询会更快。

面试官:为什么?

回答:因为主键索引树的叶子结点直接就是我们要查询的整行数据了,而非主键索引的叶子结点是主键的值,查到主键的值以后,还需要通过主键的值再进行一次查询。

面试官:刚刚你提到主键索引查询只会查一次,而非主键索引需要回表查询多次(后来我才知道,原来这个过程叫做回表)。是所有情况都是这样的吗?非主键索引一定会查询多次吗?

回答:覆盖索引也可以只查询一次。覆盖索引指一个查询语句的执行只用从索引中就能获得,不必从数据表中读取。也可以称之为实现了索引覆盖。当一条查询语句符合覆盖索引条件时,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少了IO,提高了效率。如,表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。当我们通过SQL语句:select key2 from covering_index_sample where key1 = ‘keytest’;的时候,就可以通过覆盖索引查询,无需回表。

 

3.联合索引、最左前缀匹配

面试官:在建立索引的时候都会考虑哪些因素?

回答:我们一般对查询概率比较高,经常作为where的字段设置索引

面试官:你们用过联合索引吗?

回答:用过,对一些表中创建过联合索引。

面试官:在创建联合索引的时候,需要做联合索引多个字段之间顺序你们是如何选择的?

回答:我们把识别度最高的放在前面。

面试官:为什么这么做呢?

回答:这样的话可能命中率更加高一点。

面试官:哪你知道最左前缀匹配吗?

回答:在创建多列索引时,我们根据业务需要,where子句中使用最频繁的一列放在最左边,因为MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。所以当我们创建一个联合索引的时候,如(key1,key2,key3),相当于创建了(key1)、(key1,key2)和(key1,key2,key3)三个索引,这就是最左匹配原则。

 

4.索引下推、查询优化

面试官:你们线上用的MySQL是哪一个版本?

回答:MySQL5.7

面试官:哪你知道在MySQL5.6中,对索引做了哪些优化吗?

回答:索引下推:Index Condition PushDown。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条件查询的情况下,减少回表次数。

面试官:你们创建那么多的索引,到底有没有生效,或者说你们的SQL语句有没有使用索引查询你们统计过吗?

回答:这个没有统计过,遇到慢SQL的时候我们才会去排查。

面试官:排查的时候,用什么手段可以知道有没有走索引查询?

回答:可以通过explain查看SQL语句的执行计划,通过执行计划分析索引使用情况。

面试官:什么情况下会发生明明创建了索引,但是执行的时候并没有通过索引呢?

回答:查询优化器;一条SQL语句的查询,可以有不同的执行方案,至于最终选择哪种执行方案,需要通过优化器进行选择,选择执行成本最低的方案。在一条单表查询语句真正执行之前,MySQL的查询优化器会找出执行该语句所有可能使用的方案,对比之后找出成本最低的方案。这个成本最低的方案就是所谓的执行计划。优化过程大致如下:1、根据搜索条件,找出所有可能使用的索引;2.计算全表扫描的代价;3.计算使用不同索引执行查询的代价;4.对比各种执行方案的代价,找出成本最低的那个。

面试官:线上数据的事务隔离级别是什么?

回答:

 

总结&感悟

大厂的面试主要的还是考察一个人的学习能力和对基础知识、基本理论的掌握。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值