This Friday before work, found a strange problem, presumably this background
A table with a structure of
Create Table:CREATE TABLE' out_table ' (' ID ')int( One) not NULLauto_increment, ' name 'varchar( -) not NULL, PRIMARY KEY(' id ')) ENGINE=innodbAuto_increment=36865 DEFAULTCHARSET=Latin1
There is a total of 37K rows of data, the data is probably
+----+------+|Id|Name|+----+------+| 1 |A|| 2 |B|| 3 |C|| 4 |D|| 5 |C|| 6 |C|| 7 |C|| 8 |C|| 9 |C|| Ten |A|+----+------+
Run this SQL
mysql> select ID from out_table where ID 10000 limit 1 ; + -- -----+ | ID | + -- -----+ | 10001 | + -- -----+
1 row in Set (0.00 sec)
The speed is also very fast.
But when it comes to running explain,
Mysql>ExplainSelectId fromOut_tablewhereId>10000Limit1;+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------ --------+|Id|Select_type| Table |Type|Possible_keys| Key |Key_len|Ref|Rows|Extra|+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------- -------+| 1 |Simple|Out_table|Range| PRIMARY | PRIMARY | 4 | NULL | 26358 |Usingwhere; UsingIndex |+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------- -------+
found that rows actually have,26358
View the official MySQL documentation, where rows represents the meaning
Column |
Meaning |
Rows |
Estimate of rows to be examined |
The number of rows to be detected is estimated.
However, from the DBA's intuition, the ID field is the primary key, and is the self-increment attribute, and in addition there is a limit of 1, then the rows should be no more than 1.
So does explain not consider the trailing limit 1?
Continue running SQL validation
Mysql>ExplainSelectId fromOut_tablewhereId>10000 ;+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------- -------+|Id|Select_type| Table |Type|Possible_keys| Key |Key_len|Ref|Rows|Extra|+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------- -------+| 1 |Simple|Out_table|Range| PRIMARY | PRIMARY | 4 | NULL | 26358 |Usingwhere; UsingIndex |+----+-------------+-----------+-------+---------------+---------+---------+------+-------+------------------ --------+
Sure enough, the limit 1 does not affect the value of rows at all
So how is this rows calculated? Let's look at the MySQL source code (take 5.6.23 for example).
In order to avoid the large paragraph descriptions that are not good, I pasted several key files and functions.
File |
Key Parts |
Next |
sql/opt_explain_traditional.cc " |
Push (&items, column_buffer.col_rows, nil) |
Col_rows |
sql/opt_explain.cc |
Select->quick->records |
Records |
sql/opt_range.cc |
Check_quick_select |
|
While the Check_quick_select function, the comments in the MySQL source code are
Calculate estimate of number records that'll be retrieved by a range scan on given index using given sel_arg intervals T Ree.
This method only determines how many rows need to be scanned, based on the criteria given and the index itself . It is clear that limit 1 is not directly related to this index.
So new posture, get!.
Why is it so big that in MySQL explain---write in the night before going to ACUMG to listen to the lecture