Mysql implicit type conversion may not use index?

Mysql implicit type conversion may not use index?

Have you ever discovered during the actual development and operation and maintenance process that when executing a query on a table with a large amount of data, the wherefields behind the conditions are obviously indexed, but the query takes a long time. Why is this?

Let’s talk about the conclusion first: If MySQL varcharimplicit type conversion occurs in the index of type field, the index will be invalid.

Create a user table with two attributes and and a nameprimary key field:ageid

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_name` (`name`),
  KEY `user_age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

nameWe have created indexes for the fields " and " respectively age. Let's test and verify these two indexes.

Let's try using agethe field to perform a normal type of query and see what the execution plan looks like:

mysql> explain select * from user where age = 1;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | ref  | user_age      | user_age | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

We can see that the column of the execution plan typeis displayed as refand possible_keysthe column user_ageindicates that the index may be used, while keythe value of the column user_ageindicates that user_agethe index will eventually be decided to be used.

ageThe field itself is a numeric type, so will queries that perform implicit type conversion of numeric types use indexes? We continue testing and change wherethe numbers in the condition 1to strings '1':

mysql> explain select * from user where age = '1';
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | ref  | user_age      | user_age | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

We see that the execution plan of Mysql is exactly the same and user_agethis index will still be used. Therefore, when Mysql treats implicit type conversion of int type fields, it will not cause index failure. So, will implicit type conversion of varcher type fields cause index failure? Let's continue testing.

First verify that using normal types will lead to indexing:

mysql> explain select * from user where name = '1';
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | ref  | user_name     | user_name | 768     | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

varcherYou can see the type field used after the where condition name, and =the subsequent data type uses the namesame type as the field definition . The field varcherin the above result indicates that the index is removed. Okay, let's change the string type to a numeric type and see the effect:keyuser_name'1'1

mysql> explain select * from user where name = 1;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | user_name     | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 3 warnings (0.00 sec)

Hey, we found that typethe field has changed NULL, possible_keysthe value of the field is still the same user_name, but keythe value of the field has changed NULL, indicating that Mysql still wants to use the index, but ultimately decided not to use the index.

Why is this so?

When Mysql compares values ​​with inconsistent types, it will do its best to perform the comparison. In the above case, the field nameis varcharof type, but the where name = 1;in the statement 1is of numeric type. At this time, Mysql nameconverts the field value into a floating point number for comparison, but in the index All stored are strings, so each record value needs to be converted, which requires a full table scan.

Guess you like

Origin blog.csdn.net/booynal/article/details/125931371