查询无法解析索引的几种情况

版权声明:本文为博主原创文章,未经博主允许不得转载。 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从入门到精通





猜你喜欢

转载自blog.csdn.net/ma2595162349/article/details/80414752