索引失效:建了索引,但是查詢時沒有用到。
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)