1) mysql为甚用b+树索引(innodb)
不用普通的二叉树,因为对于大的数据量,二叉树的高度太高,索引的效率低下。这里主要说明为什么不用B树(B-树就是B树),而是用B+树。
二叉树查询的时间复杂度为O(logN),查询效率已经够高了,但为什么还要有B树和B+树呢?答案是磁盘IO。
平衡二叉树由于树的高度太大造成磁盘IO读写过于频繁,从而导致效率低下,所以多路查找树-B树/B+树应运而生。
2) 联合索引:
mysql可以将多个列按照顺序作为一个索引,这种索引叫做联合索引。
3) 索引的最左前缀原则
索引的最左匹配原则是:假如索引列分别为A,B,C,顺序也是A,B,C,那么:
· 查询的时候,如果查询【A】,【A,B】,【A,B,C】,可以使用索引查询。
· 如果查询的时候,查询【A,C】,由于中间缺失了B,那么C这个索引是用不到的,只能用到A索引。
· 如果查询的时候,查询【B】,【B,C】或【C】,由于缺失了最左前缀A,那么是用不到这个联合索引的,除非有其他索引。
· 如果查询的时候使用范围查询,并且是最左前缀,那么可以用到索引,但是范围后面的字段无法用到索引。
4) 建索引的其他原则
1、尽量选择区分度高的列作为索引,区分度公式:count(distinct col)/count(*),表示字段不重复的比例,比例越大,我们扫描的记录数就越少,唯一性的列的区分度为1。这就是为什么不建议在状态,性别这样区分度很小的列上建立索引的原因。
2、索引列在sql语句中不能参与运算,否则会导致索引失效。例如from_unixtime(create_time) = ’2021-07-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。应该改成create_time = unix_timestamp(’2021-07-29’);
3、联合索引比单个索引的性价比更高。例如,建立【A,B,C】这个联合索引,相当于建立了【A】,【A,B】,【A,B,C】这三个索引。这就要求我们尽量的扩展索引而不是新建索引,具体情况还需具体分析。
4、频繁进行查询的字段应该新建索引,与其他表进行关联的字段可以考虑新建索引,查询中排序的字段可以考虑建立索引以提高排序的效率(这里举个例子,很多时候查询记录希望按照创建时间倒序返回,通常有人会这样做order by create_time desc,但是如果create_time不是索引,而这个表有自增主键id,那么order by id desc返回结果一样,但是效率会提高)。
5) 是否走索引
show keys from table. -- 执行查看所有索引