Just because I wrote a wrong SQL statement, I was invited by the manager to "climb", shivering

Foreplay

The SQL is wonderful, the salary increase is croaking!

The new intern Xiao Yang wrote a SQL statement

SELECT wx_id from `user` WHERE wx_id = 2

When Xiao Yang couldn't wait to get home from work, the manager Wang next door grabbed Xiao Yang and used the EXPLAIN command to educate Xiao Yang. Xiao Yang shed tears of uncultured tears.

In this SQL statement, wx_id is indexed, but the result found by Manager Wang is like this

image

Xiao Yang took a closer look at the key field displayed as Null. It was obvious that this SQL statement was not indexed.

Xiao Yang thought "Oops, I wrote the wrong SQL statement again. Now I am facing a mixed doubles of operation and maintenance and manager. No, I have to change this SQL statement immediately and let me think about what went wrong."

image

Xiao Yang's head was crazy, thinking about the table structure carefully, and suddenly he thought that the wx_id field is of varchar type, and he didn't even add quotation marks when querying.

Xiao Yang snatched the keyboard in the manager's hand and added quotation marks to the query condition of wx_id. The result

image

Sure enough, this SQL statement began to index. Xiao Yang is complacent and thinks that he has solved a huge bug.

The manager smiled and asked, "Do you know why the index is gone after adding quotation marks? If the field is of type int, do you need to add quotation marks when querying? And why?"

Dinner is here

Xiao Yang stayed where he was asked, unable to answer.

After Xiao Yang's research, it is found that if the field is of varchar type, quotation marks must be added to the right of the equal sign before indexing; if the field is of type int, then the quotation marks on the right of the equal sign will be indexed.

what? You don't believe what Xiao Yang said, there are pictures and the truth. (The bonus field type is int)

image

But when the conclusion came out, he still couldn't answer the manager's three life-threatening questions.

Xiao Yang moved the answer

The owner of Ma'erdudu told Xiao Yang

In MySQL queries, implicit conversion occurs when the types on the left and right sides of the query condition do not match

也就是说
SELECT wx_id from `user` WHERE wx_id = 2
等价于
SELECT wx_id from `user` WHERE CAST(wx_id AS signed int) = 2

Once the function operation is performed on the index field, MySQL will give up using the index

So if the field is of varchar type, quotes must be added to the right of the equal sign before indexing, otherwise MySQL will give up using the index due to implicit conversion. So why can int use indexes with or without quotation marks?

That's because only 2 of int type numbers can be converted to '2', which is the only certainty. So although implicit conversion is required, it does not affect the use of indexes

Xiao Yang asked: "Can you still tell me some knowledge of implicit conversion?"

The number master backhand is an English document

If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.

If both arguments in a comparison operation are strings, they are compared as strings.

If both arguments are integers, they are compared as integers.

Hexadecimal values are treated as binary strings if not compared to a number.

If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.
A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.

If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.

In all other cases, the arguments are compared as floating-point (real) numbers.

Sweetheart, I help you translate into Chinese

1, 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 
对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换

2, 两个参数都是字符串,会按照字符串来比较,不做类型转换

3, 两个参数都是整数,按照整数来比较,不做类型转换

4, 十六进制的值和非数字做比较时,会被当做二进制串

5, 有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp

6, 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数会将整数转换为 decimal 后进行比较,
   如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较

7, 所有其他情况下,两个参数都会被转换为浮点数再进行比较

Share another pit of implicit conversion

  • Do you occasionally delete some unknown data?
mysql> select * from test;
+----+-------+-----------+
| id | name  | password  |
+----+-------+-----------+
|  1 | test1 | password1 |
|  2 | test2 | password2 |
|  3 | aaa   | aaaa      |
|  4 | 55aaa | 55aaaa    |
|  5 | 1212  | aaa       |
|  6 | 1212a | aaa       |
+----+-------+-----------+
6 rows in set (0.00 sec)

mysql> select * from test where name = 1212;
+----+-------+----------+
| id | name  | password |
+----+-------+----------+
|  5 | 1212  | aaa      |
|  6 | 1212a | aaa      |
+----+-------+----------+
2 rows in set, 5 warnings (0.00 sec)

mysql> select * from test where name = '1212';
+----+------+----------+
| id | name | password |
+----+------+----------+
|  5 | 1212 | aaa      |
+----+------+----------+
1 row in set (0.00 sec)

The above example is intended to query the record with id 5, and as a result, the record with id 6 is also queried. What do I want to explain? Sometimes some of the columns in our database tables are of varchar type, but the stored value is a pure numeric string value such as '1123'. Some students are not used to adding quotes when writing SQL. In this way, some data may be manipulated when selecting, updating or deleting. So don't forget where you should put quotation marks.

all in all

Implicit type conversion has the risk of not hitting the index. In the case of high concurrency and large data volume, the consequences of not hitting the index can not only be mixed by operation and maintenance and managers! And write SQL and EXPLAIN

Guess you like

Origin blog.csdn.net/yunduo1/article/details/108735976