1.没有加索引;会导致全表扫描。应考虑在where的条件列;建立索引;尽量避免全表扫描。
select * from user_info where name =;1; ;
//添加索引
alter table user_info add index idx_name (name)
2.索引不生效
类型不匹配;mysql会做隐式的类型转换;把它们转换为浮点数再做比较。隐式的类型转换;索引会失效。
对于or;没有索引的age这种情况;假设它走了userId的索引;但是走到age查询条件时;它还得全表扫描;也就是需要三步过程;全表扫描;索引扫描;合并。
如果它一开始就走全表扫描;直接一遍扫描就完事。Mysql优化器出于效率与成本考虑;遇到or条件;让索引失效;看起来也合情合理嘛。
注意;如果or条件的列都加了索引;索引可能会走也可能不走;大家可以自己试一试哈。但是平时大家使用的时候;还是要注意一下这个or;学会用explain分析。遇到不走索引的时候;考虑拆开两条SQL。
并不是用了like通配符;索引一定会失效;而是like查询是以%开头;才会导致索引失效。
既然like查询以%开头;会导致索引失效。我们如何优化呢?
使用覆盖索引
把%放后面
MySQl建立联合索引时;会遵循最左前缀匹配的原则;即最左优先。如果你建立一个;a,b,c;的联合索引;相当于建立了(a)、(a,b)、(a,b,c)三个索引。
虽然login_time加了索引;但是因为使用了mysql的内置函数Date_ADD();索引直接失效;
例;select * from user where DATE_ADD(login_time ,INTERVAL 1 DAY);= ;2022-05-22 00:00:00;;
可以把内置函数的逻辑转移到右边
例;select * from user where login_time = DATE_ADD(;2022-05-22 00:00:00;,INTERVAL 1 DAY);
selec * from user where age-2=10;
建议;不可以对索引列进行运算;可以在代码处理好;再传参进去。
虽然age加了索引;但是使用了;= 或者< >;not in这些时;索引如同虚设。
selec * from user where age!=10;
selec * from user where age<>10;
其实这个也是跟mySQL优化器有关;如果优化器觉得即使走了索引;还是需要扫描很多很多行的哈;它觉得不划算;不如直接不走索引。平时我们用;= 或者< >;not in的时候要注意。
很多时候;也是因为数据量问题;导致了MySQL优化器放弃走索引。同时;平时我们用explain分析SQL的时候;如果type=range,要注意一下哈;因为这个可能因为数据量问题;导致索引没无效。
做表关联时;注意一下关联字段的编码问题
MySQL 中一张表是可以支持多个索引的。你写SQL语句的时候;没有主动指定使用哪个索引的话;用哪个索引是由MySQL来确定的。
我们日常开发中;不断地删除历史数据和新增数据的场景;有可能会导致MySQL选错索引。那么有哪些解决方案呢?
使用force index 强行选择某个索引
修改你的SQl;引导它使用我们期望的索引
优化你的业务逻辑
优化你的索引;新建一个更合适的索引;或者删除误用的索引。