版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ma2595162349/article/details/80414752
mysql使用索引能提高查询效率,但在有些情况下,你使用索引查询,索引并没有起作用。
mysql> select * from stu;
+------+------+----------+
| id | age | name |
+------+------+----------+
| 1 | 1 | zhangsan |
| 2 | 2 | lisi |
| 3 | 3 | wangwu |
| 4 | 4 | zhaoliu |
| 5 | 5 | sunqi |
+------+------+----------+
5 rows in set (0.00 sec)
mysql> show index from stu;
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| stu | 1 | index_name | 1 | name | A | 5 | NULL | NULL | YES | BTREE | | |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
可以看到stu表中的name字段为该表的索引。
mysql> explain select * from stu where name like 'z%';
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | stu | NULL | range | index_name | index_name | 23 | NULL | 2 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from stu where name like '%i';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | stu | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 20.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
由结果可以看到,like 'z%'使用了索引查询,而like '%i'没有使用索引查询。key为index_name表示使用了索引查询。
关于like的查询:如果匹配字串的第一个字符为'%',索引不会起作用。只有'%'不在第一个位置,索引才会起作用。
mysql> create index index_id_age on stu(id,age);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from stu;
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| stu | 1 | index_id_age | 1 | id | A | 5 | NULL | NULL | YES | BTREE | | |
| stu | 1 | index_id_age | 2 | age | A | 5 | NULL | NULL | YES | BTREE | | |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
mysql> explain select * from stu where id=4;
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | stu | NULL | ref | index_id_age | index_id_age | 5 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from stu where age=4;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | stu | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 20.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
我们为表stu创建了一个多列索id和age。当我们单独使用id时,查询使用了索引;而当单独使用age时,查询没有使用索引。则对应多列索引,只有当查询使用了这些字段的第一个字段时,索引才会被使用。
当查询条件使用or关键字时,且or前后的两个条件中的列都是索引时,查询中才使用索引。否则将不使用索引。
我目前机器上测试的结果是:or前后都使用索引,查询还是不用索引,不知何故。感兴趣的读者可以在自己mysql上尝试一下。
参考资料:mysql从入门到精通