searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

limit条件下explain语句rows问题

2023-10-26 02:45:26
14
0
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行即可。
 
0条评论
0 / 1000
z****n
18文章数
1粉丝数
z****n
18 文章 | 1 粉丝
原创

limit条件下explain语句rows问题

2023-10-26 02:45:26
14
0
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行即可。
 
文章来自个人专栏
数据库运维专项
18 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0