索引失效:建了索引,但是查询时没有用到。
staffs表:
create table staffs(
id int primary key auto_increment,
name varchar(24) not null default '' comment '姓名',
age int not null default 0 comment '年龄',
pos varchar(20) 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 ('july' ,23 ,'manager',now());
insert into staffs(name,age,pos,add_time) values ('2000' ,23 ,'manager',now());
alter table staffs add index idx_name_age_pos(name,age,pos);
1.全值匹配最合适
2.最佳左前缀法则,索引的第一个字段不能丢,中间字段不能跳。
3.不在索引列上做任何操作(计算,比较,类型转换等)
4.存储引擎不能使用范围查找中右边的列
5.尽量使用覆盖索引(只访问索引的查询,即减少使用select *)
6.!= > <会导致索引失效(mysql8不会)
7.is null ,is not null无法使用索引(mysql8不会)
8.like以通配符开始(% _)会导致索引失效(mysql8不会)
如何解决这个问题?
用覆盖索引解决。
9.字符串不加单引号导致索引失效(mysql8不会)
10.or导致索引失效
mysql> explain select * from staffs where name = 'july';
+----+-------------+--------+------------+------+------------------+------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+------------------+------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | staffs | NULL | ref | idx_name_age_pos | idx_name_age_pos | 74 | const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+------+------------------+------------------+---------+-------+------+----------+-------+
mysql> explain select * from staffs where name = 'july' and age = 23;
+----+-------------+--------+------------+------+------------------+------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+------------------+------------------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | staffs | NULL | ref | idx_name_age_pos | idx_name_age_pos | 78 | const,const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+------+------------------+------------------+---------+-------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from staffs where name = 'july' or age = 23;
+----+-------------+--------+------------+------+------------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+------------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | staffs | NULL | ALL | idx_name_age_pos | NULL | NULL | NULL | 3 | 55.56 | Using where |
+----+-------------+--------+------------+------+------------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
(mysql8除外)
mysql> explain select name,age,pos from staffs where name <> 'july' ;
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | staffs | NULL | range | idx_name_age_pos | idx_name_age_pos | 74 | NULL | 2 | 100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select name,age from staffs where pos <> 'man';
+----+-------------+--------+------------+-------+---------------+------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+------------------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | staffs | NULL | index | NULL | idx_name_age_pos | 140 | NULL | 3 | 66.67 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql 8> explain select age from staffs where age = '22';
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | staffs | NULL | index | idx_name_age_pos | idx_name_age_pos | 140 | NULL | 3 | 33.33 | Using where; Using index |
+----+-------------+--------+------------+-------+------------------+------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.07 sec)