问题描述
当SELECT语句中使用SLEEP时,何时触发SLEEP操作?
模拟测试
mysql> show create table tb1001 G
*************************** 1. row ***************************
Table: tb1001
Create Table: CREATE TABLE `tb1001` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) NOT NULL,
`c2` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNI_C1` (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
mysql> select sleep(1),id,c1 from tb1001 where c2<2 limit 3;
+----------+----+----+
| sleep(1) | id | c1 |
+----------+----+----+
| 0 | 1 | 1 |
+----------+----+----+
1 row in set (1.01 sec)
mysql> select sleep(1),id,c1 from tb1001 where c2<1;
Empty set (0.00 sec)
mysql> select sleep(1),id,c1 from tb1001 where c2<2;
+----------+----+----+
| sleep(1) | id | c1 |
+----------+----+----+
| 0 | 1 | 1 |
+----------+----+----+
1 row in set (1.00 sec)
mysql> select sleep(1),id,c1 from tb1001 where c2<3;
+----------+----+----+
| sleep(1) | id | c1 |
+----------+----+----+
| 0 | 1 | 1 |
| 0 | 2 | 2 |
+----------+----+----+
2 rows in set (2.00 sec)
mysql> select sleep(1),id,c1 from tb1001 where c2<4;
+----------+----+----+
| sleep(1) | id | c1 |
+----------+----+----+
| 0 | 1 | 1 |
| 0 | 2 | 2 |
| 0 | 3 | 3 |
+----------+----+----+
3 rows in set (3.00 sec)
测试分析
从上面的测试结果看,由于C2上没有索引,需要全表扫描,查询执行时间和查询返回的数据行记录成正比,与查询扫描的记录行数无关。
在<深入理解MySQL主从原理>书中描述:
- 每当InnoDB层返回一行数据经过WHERE条件判断后,都会触发Sleep函数,也就是经过WHERE条件过滤的数据,在发送给客户端前都会进行异常SLEEP操作。
扩展知识
可以通过LIMIT来限制发送给客户端的操作,因此可以通过SLEEP+LIMIT操作来控制语句执行时间,方便模拟执行时间较长的SQL。
mysql> select sleep(1),id from tb1001 limit 1;
+----------+----+
| sleep(1) | id |
+----------+----+
| 0 | 1 |
+----------+----+
1 row in set (1.01 sec)
mysql> select sleep(1),id from tb1001 limit 2;
+----------+----+
| sleep(1) | id |
+----------+----+
| 0 | 1 |
| 0 | 2 |
+----------+----+
2 rows in set (2.00 sec)