At work, I often encounter such a problem. I obviously added an index to the MySQL table, but why is the index not used when executing the SQL query?

The same SQL query sometimes uses an index, but sometimes it doesn't. What's going on?

The reason may be that the index is invalid. The reasons for the failure are as follows. Have you ever stepped on a similar pit?

1. Data preparation:

There is such a user table, create an index on the name field:

 CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB COMMENT='用户表';

2. Explain in detail:

Want to see if an SQL uses an index? What type of index is used?

You can use the explain keyword to view the SQL execution plan. E.g:

 explain select * from user where id=1;

image-20220629230715808.png

You can see that type=const, indicating that the primary key index is used.

All types of explain are as follows:

image-20220630000000083.png

3. Reasons for failure

1. Implicit conversion of data types

The name field is of varchar type. If we use the data type query, data type conversion will occur. Although no error is reported, the index cannot be used.

 explain select * from user where name='一灯';

image-20220629231442732.png

 explain select * from user where name=18;

image-20220629231513592.png

2. Fuzzy queries like start with %

 explain select * from user where name like '张%';

image-20220629231905411.png

 explain select * from user where name like '%张';

image-20220629231938893.png

3. The index is not used before and after or at the same time

Although an index is added to the name field, the age field does not have an index, and a full table scan is performed when using or.

 # or前后没有同时使用索引,导致全表扫描
explain select * from user where name='一灯' or age=18;

image-20220629232130791.png

4. Joint index, not using the first column index

If we build a joint index on (name, age), but only the age field is used in the query condition, the index cannot be used.

With a union index, you must follow the leftmost match principle, using the first column field first, then the second column field.

 CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

image-20220630000609202.png

5. Perform calculations on index fields

If we perform a calculation operation on the index column, the index cannot be used.

 # 在主键索引上进行计算操作,导致全表扫描
explain select * from user where id+1=2;

image-20220629233208133.png

6. Use functions on index field fields

If we use the function on the index column, the index will not be used.

image-20220629233447426.png

7. The optimizer chooses the wrong index

The same SQL query sometimes uses an index, but sometimes it doesn't. What's going on?

This may be the result of the optimizer's choice whether to use an index or not based on the amount of data in the table.

image-20220629234641204.png

When most of the names in the table are one lamp, then use name='one lamp' to query, will the index be used?

The index optimizer will think that using an index is not as fast as a full table scan, so don't use an index at all.

image-20220629234900354.png

Of course, we think that the optimizer is not optimizing correctly, and we can also use force index to force the use of the index.

image-20220629235137298.png

Summary of knowledge points:

image-20220630171538701.png

The article is continuously updated, and you can search for "One Light Architecture" on WeChat to read more technical dry goods as soon as possible.

一灯架构
44 声望11 粉丝