1、在哪些情况下适合添加索引:
1)DML语句很少出现
2)查询语句中多出现where限制条件
3)数据量大
2、为什么索引底层采用B+树的数据结构?
在常用的DQL中我们可以知道索引数据结构必须满足以下几点要求:
1)根据某个值快速查找
2)根据某个区间快速查找
3)支持快速排序查找和逆序查找
哈希索引并不是按照索引值顺序排序的,因此无法根据区间快速查找,且不支持范围查找。
B+树是由平衡二叉树演变而来的
平衡二叉树具有的性质:
1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2)若右子树不空,则右子树上所有节点的值均大于或等于它的根节点的值;
3)每个非叶子节点的左右子树的高度之差的绝对值(平衡因子)最多为1。
从其特性我们可以看出平衡二叉树查找结点的时间复杂度是O(log2n)
再将其改造为B+树则是
最终形态,相应的行记录就放在最后的子节点中
查找时只需要从头节点开始依次向下逐层判断即可找到我们需要的节点或区间。假设有1亿个节点,我们查找时,需要的次数为log21亿=27次,速度非常快,但这一亿个节点的内存占用就会非常大,如果将其放在磁盘,那27次的IO又会非常消耗性能,因此我们再次对其进行优化。我们观察可以发现,在相同的节点数下,分叉越多则层数越少,层数越少则速度越快,理想情况下似乎树分叉越多越好,但是需要考虑到MySQL中页的默认值为16KB,因此B+树的节点最好设置为页的大小为最佳。
补充一点,页的大小并不是越大越好,虽然越大节点能够容纳的数据就越多,树高就越小,IO次数会变少,但是InnoDB是通过内存中的缓存池来管理从磁盘中读取的页数据的,页太大很快就会把缓存池撑满,可能会造成页在内存与磁盘间频繁换入换出,影响性能。
3、为什么主键推荐使用自增id而不是自建主键
如果单是考虑主键不能重复以及不能为空的要求,我们在建表时可以使用如用户名及客户身份证等不能重复的字段作为主键。但是B+树为了维护索引的有序性,每插入或更新一条记录的时候,会对索引更新,所以如果以像身份证这样的完全随机无序的值在插入的时候就会很容易造成页分裂,分裂造成的调整必然容易导致性能下降,但是如果采用自增id作为主键,那么新插入的id则一定比其他主键值都大,要么就会直接放入到已存在但未满的节点中,要么就会放入新建节点中,就不存在页分裂的问题,性能就会得到提升。
4、索引失效的情况
1)模糊查询时,第一个通配符使用的是%,这时索引就会失效,还是采用全表扫描
2)使用OR时前后没有同时使用索引
3)数据类型出现隐式转换(varchar不加单引号可能会自动导致转换为int型)
5、如何查看扫描方式
在DQL前添加explain则可以查看到扫描方式
(未完待续)