总结数据库索引知识点

索引失效

1.隐式转换导致索引失效:
select * from users where name>123
(要把123转成字符串)
2.组合索引,当 前面的索引包含一个范围判断,将不调用后面的索引
select * from uses where name>“aaa” and age = 15
这时,只用了name的索引
3.组合索引违反匹配最左原则
4.单列索引查询,用到“or“,会使用索引,组合索引不会使用
5.当查询条件是表达式,函数的时候,不会使用原本的索引
比如:执行 select * from users where id=4,用到主键索引,直接索引覆盖了,不用回表,效率很高。而执行
select * from users where id+1=4时,当explain时会发现用到的key不是主键而是其他的,由于需要回表,效率大大降低。

索引下推

对于联合索引查询,
如select * from users where username like (刘%)and age = 30
其中(username,age) 建了联合索引,主键为id
当没有索引下推时,数据库服务器将忽略第二个条件,将第一个条件传给存储引擎,存储引擎将一大堆姓刘的主键id返回给服务器,服务器根据每一个主键id,一次一次回表查行的所有信息,在进行筛选,返回最终结果;
当用到索引下推,innodb两个条件都会考虑,在索引树种,直接找出满足这两个条件的主键id,返回给服务器,返回的数目要比不采用索引下推的少,进而减少了后续回表的次数

索引覆盖:

主键索引创建的b+tree叶子节点是整行,其他索引创建的b+tree叶子节点是主键值。
根据主键索引查某个字段,由于索引的树的叶子节点是整行数据,所查的字段就在整行数据中,这就是索引覆盖一种情况。

回表

根据非主键索引查除改索引key的非主键的字段,由于该索引树的叶子节点并没有该字段,而只有主键值,所以只能从该主键索引创建的树中查改字段,这就是回表

总之,会产生回表的查找,是select 非索引key,非主键的字段,特别注意的是当所查的字段一旦含有非索引key,为主键的字段,也不会索引覆盖。
索引覆盖和回表是互斥的两个概念

索引优化小结:

1、当使用索引进行查询,尽量不要使用表达式,函数,把计算放到业务层而不是数据库层
2、尽量使用主键索引,因为主键索引会不回表,回表浪费效率的原因是i/o次数增加
3、对于varchar可以取前几个字符建立索引
4、order by的字段尽量建立索引,因为索引本身就是有序的。当我们对需要排序的sql查执行计划的时候,在Exter字段里有using filesort,他的意思是排序创建了临时文件,而没用到索引。
5、能使用limit尽量使用,能够减少io。查询条件中出现in、all、or都有可能使用到索引,但是推荐使用in
如:select * from users where id = 1;
select * from users where id = 2;
尽量使用:select * from users where id in(1,2)
6、强制类型转换不用索引,上面提到的隐式转换
7、区分度:count(distinct(列名))/count(*)>80%,就有资格建索引,像性别,民族,stata这样的没必要建。
8、单列索引尽量不要超过5个,组合索引的key不要超过5个

猜你喜欢

转载自blog.csdn.net/qq_44477844/article/details/107922974