面试之索引---------如果不能吊打面试官,找我扯皮*

** 面试之索引---------如果不能吊打面试官,找我扯皮*

为了保证面试的真实性,我们分为两个角色,一为面试官,一位求职者

面试官:对于数据库查询优化,你有什么看法吗?
求职者:可以使用数据库索引技术,快速进行定位查询。
面试官:那你说说索引有哪些类型?
求职者:分为以下几种:主键索引,普通索引,联合索引等。
面试官:那索引的实现原理呢?
求职者:为了更加生动的让大家理解,我通过画图详述:

首先,数据库索引的底层数据结构是使用的B+树。但是实现每个数据库的引擎对B+树的实现是不一样的。就以MyISAM
和InnoDB为例,下面请看图:

这张图为MyISAM引擎实现B+树,大家都知道B+树分为叶子节点和非叶子节点,正是因为叶子节点,B+树的范围查询的效率是非常非常高的,因为他可以直接定位到你的叶子节点,如果是B树或者平衡二叉树,虽然是可以支持范围查询,但是效率·是极低的,这张图就是查找到你的叶子节点,找到你的Value值,MyISAM引擎的Value值为一串地址,通过地址可以直接定位到该行。查询的效率也是非常快的。
首先
这张图片为InnoDB引擎,他的实现B+树的原理是直接将对应的值缓存到叶子节点的Value值。查询的速度是非常非常快的。

对比这两种引擎:
InnoDB引擎比较占硬盘的,因为要将所有的数据缓存到Value值中,但是查询的速度要比MyISAM块很多的。
MyISAM引擎查询效率更低,是因为需要查到对应的Value值,然后通过Value值的地址再去定位到该行。效率上会比InnoDB低很多。

最后再来说一说MySql索引会使用B+树,大家知道,索引的数据结构是很多的,这点必须要给面试官谈到。

我们来盘点一下数据库有哪些索引:
Hash,平衡二叉树,B树,B+树等,

Hash的优缺点
Hash我就不用去过多解释了,大家都知道,是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

优点:查询够快,直接通过Key定位到对应的值。
缺点:因为它是散列的,所以不支持范围查询。

平衡二叉树的优缺点
以下是一颗平衡二叉树,所谓平衡二叉树,就是追求极致平衡。它 的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值(平衡因子 ) 不超过1。 也就是说AVL树每个节点的平衡因子只可能是-1、0和1(左子树高度减去右子树高度)。
优点:查询是非常快的,比如,查询10,只需要查询4,8,9,10。就可以查询到10.只需要查询4次。
缺点:虽然支持范围查询但是,使用回旋算法,效率还是很低。
在这里插入图片描述
B树的优缺点
以下是一颗B树,B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树

优点:继承了平衡二叉树的优点,但是自身做出了优化,对比平衡二叉树,B树明显是变矮了,这样的话,查10这个数,只需要查询三次,由于节点较多,这样会大大的减少IO磁盘操作。
缺点:使用回旋算法,范围查询效率低。
在这里插入图片描述
最后说一说B+树,我们的压轴选手,B+树的实力是不会让我们失望的

没错,这是一颗B+树,B+树相比B树,新增叶子节点与非叶子节点关系,叶子节点中包含了key和value,非叶子节点中只是包含了key,不包含value。
优点:集成了B树和平衡二叉树的优点,同时,它的叶子节点为顺序排列,这样它的查询范围的效率是非常的高的,举个例子
我们现在查询大于1的所有的数,直接就可以定位到1,将叶子节点1以后的数全部返回给客户端。
缺点:由于叶子节点记录相同的值,从一定程度来说会耗费硬盘。

在这里插入图片描述
面试官:心里在想(我去,这小伙子能把索引了解的这么透彻。厉害,折服)
面试官:那你说说数据库的优化方案?
求职者:分为三种,开启慢查询,对索引进行优化,表进行优化。

面试官:那你说一说索引为什么会失效呢?
求职者:这就太多了。
1.索引无法存储null值
2.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
3.对于多列索引,不是使用的第一部分,则不会使用索引
4.like查询以%开头
5.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
6.如果mysql估计使用全表扫描要比使用索引快,则不使用索引

面试官:那你说说为什么联合索引应该注意哪些情况?
求职者:联合索引的必须加上左前缀。
面试官:为什么?
求职者:这就要说到索引的底层了,因为索引的底层是B+树。使用叶子节点进行顺序排序,就以联合索引为ID何userName为例子,(1,sunyang1 1,sunyang2),(2,sunyang1 2,sunyang2),(3,sunyang1 3,sunyang2)
这个时候你如果是这样写sql:EXPLAIN select * from user_details WHERE id=1 and user_name=‘sunyang1’;索引是生效的。EXPLAIN select * from user_details WHERE user_name=‘sunyang1’;这个是不生效的。
必须通过左前缀索引才能定位到具体的节点范围,如果你输入sunyang1,他就会进行全表扫描

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值