mysql索引优化
索引优化
# 创建表 和数据
create table IF NOT EXISTS staffs(
id int primary key auto_increment,
`NAME` varchar(24) not null default '' COMMENT'姓名',
age int not null default 0 COMMENT'年龄',
pos varchar(24) not null default '' COMMENT'职位',
add_time TIMESTAMP not null default CURRENT_TIMESTAMP COMMENT'入职时间'
);
insert into staffs(`NAME`,age,pos,add_time) values('z3',22,'manager',NOW());
insert into staffs(`NAME`,age,pos,add_time) values('judy',22,'dev',NOW());
insert into staffs(`NAME`,age,pos,add_time) values('gc',22,'dev',NOW());
# 添加索引
alter table staffs add index idx(name , age,pos);
分析该数据列:
explain select * from staffs where name
= ‘z3’ and age
= ‘z3’ and pos = ‘123’
explain select * from staffs where name
= ‘z3’
explain select * from staffs where name
= ‘z3’ and pos = ‘123’
explain select * from staffs where age
= ‘z3’ and pos = ‘123’
1,复合索引,需要按照建索引的顺序列查询,如果中间去掉了一列后,则后面的索引会失效,如果第一列索引都不匹配,则索引全失效
explain select * from staffs where name
= ‘z3’
explain select * from staffs where left(name
,4) = ‘z3’
2,在索引列上做任何操作(计算,函数、(自动或手动)的类型转换),会导致索引失效而转向全表的扫描
explain select * from staffs where name
= ‘z3’ and age
> ‘3’ and pos = ‘123’
3,存储引擎不能使用索引中范围条件右边的列(也就是范围条件后面的索引会失效)
explain select name
,age,pos from staffs where name
= ‘z3’ and age
= ‘3’ and pos = ‘123’
4,尽量使用覆盖索引(只访问索引列上存在的字段),减少select * 的查询(同时如果此时以3的示例,效率也会更高)
explain select * from staffs where name
<> ‘z3’
5,mysql在使用不等号(!= 或 <>) 的时候,会导致无法使用索引会导致全表扫描(但是 select 索引列 from … 不会导致索引失效,因为用到覆盖索引了)
explain select * from staffs where name
is null
explain select * from staffs where name
is not null
6,is null 或 is not null 也无法使用索引
explain select * from staffs where name
like ‘judy%’
explain select * from staffs where name
like ‘%judy%’
explain select * from staffs where name
like ‘%judy’
like 百分号最好放右边,才会避免索引失效,且后面的索引也不会失效
那么如果愣头轻,两遍都要百分号怎么办
explain select name
from staffs where name
like ‘%judy%’
7,两遍百分号,查询字段如果是覆盖索引,那么索引页不会失效了
explain select * from staffs where name
= ‘33’
explain select * from staffs where name
= 33
8,字符串查询不加单引号索引会失效(同时也就是2演示所说,(自动或手动)的类型转换)
explain select * from staffs where name
= ‘33’ or name
= ‘123’
9,少用or,用它连接的时候索引会失效