sql语句添加limit限制条件之后,执行计划explain中显示的rows可能不太准确,本文通过实验以及从原理上来解释了这一现象
实验测试:
实验测试limit条件下,explain显示的rows问题,一下是创建的测试表以及相关索引
1、建表语句:
1 CREATE TABLE `temp` (
2 `TYPE` varchar(64) NOT NULL,
3 `CREATED_AT` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
4 KEY `IDX_TEMP_type_createdAt` (`CREATED_AT`)
5 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
2、插入测试语句
1 mysql> select * from temp;
2 +‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
3 | TYPE | CREATED_AT |
4 +‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
5 | A | 2019‐02‐13 11:33:21.160914 |
6 | A | 2019‐02‐13 11:33:26.599419 |
7 | A | 2019‐02‐13 11:33:28.880621 |
8 | A | 2019‐02‐13 11:33:29.772634 |
9 | A | 2019‐02‐13 11:33:30.544576 |
10 | B | 2019‐02‐13 11:33:35.960124 |
11 | B | 2019‐02‐13 11:33:36.723192 |
12 | B | 2019‐02‐13 11:33:38.156267 |
13 | B | 2019‐02‐13 11:33:38.762312 |
14 | B | 2019‐02‐13 11:33:40.345495 |
15 | B | 2019‐02‐13 11:39:46.056952 |
16 | B | 2019‐02‐13 11:39:47.042967 |
17 +‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
18 12 rows in set (0.00 sec)
类型为A的一共5调记录,类型为B的一共7调记录。
实验一:
首先EXPLAIN实验语句:
rows显示为两行,但实际执行结果如下: 执行语句前:
执行语句:
执行语句后:
实际访问的行数为9行,即7行B加上满足条件的2行A.
实验二:
将降序改为升序,让其从前开始扫描。
rows显示为两行,但实际执行结果如下: 执行语句前:
执行语句
执行后:
此时正在的只扫描了两行。
结论: 添加limit添加之后,explain中显示的rows不太准确,实际扫描行数通过handler状态变 量查看,并且实际扫描行数与是否走索引以及走索引的方式有很大的关系。 对于实验一,走IDX_TEMP_type_createdAt时间索引,并且是降序,也就是从后向前扫 描,故而先扫面了全部B类型(不满足where条件),然后才扫面到A类型,直到满足limit设 置的2两条记录为止。所以一共7+2=9行。实验发现,如果增加B类型(时间直到以默认 值),则扫描行数相应增加。 对于实验二,也是走IDX_TEMP_type_createdAt时间索引,但是是升序,所以从前向前 扫面,首先扫描到A,满足where条件,直接只需要扫面2行即可。