关于MySQL sleep()函数,很多同学会觉得这个很简单,但是在和研发同学沟通时发现,很多人对此函数存在误解,本文举3个典型的例子进行说明。
1.误区一
以下SQL的运行结果是什么样的
代码语言:javascript复制SELECT NOW(),SLEEP(2),NOW();
很多人会认为得到的结果中第二个now()的结果是第一个now()的结果的加2s。但实际运行的结果是什么呢?
代码语言:javascript复制mysql> SELECT NOW(), SLEEP(2), NOW();
--------------------- ---------- ---------------------
| NOW() | SLEEP(2) | NOW() |
--------------------- ---------- ---------------------
| 2023-11-21 20:11:41 | 0 | 2023-11-21 20:11:41 |
--------------------- ---------- ---------------------
1 row in set (2.00 sec)
实际结果前后2个值是一致的。
那如果想前后不一致,则需要改为SYSDATE()函数,例如:
代码语言:javascript复制mysql> SELECT NOW(), SLEEP(2), SYSDATE();
--------------------- ---------- ---------------------
| NOW() | SLEEP(2) | SYSDATE() |
--------------------- ---------- ---------------------
| 2023-11-21 20:13:15 | 0 | 2023-11-21 20:13:17 |
--------------------- ---------- ---------------------
1 row in set (2.00 sec)
mysql> SELECT NOW(),SYSDATE(), SLEEP(2), SYSDATE();
--------------------- --------------------- ---------- ---------------------
| NOW() | SYSDATE() | SLEEP(2) | SYSDATE() |
--------------------- --------------------- ---------- ---------------------
| 2023-11-21 20:13:32 | 2023-11-21 20:13:32 | 0 | 2023-11-21 20:13:34 |
--------------------- --------------------- ---------- ---------------------
1 row in set (2.00 sec)
以上是在MySQL5.7环境下执行的结果,有人会问8.0中会不会有变化呢,但其实运行结果也是一致。
2. 误区二
”sleep(n)中的n只能是正整数,如果是小数会进行取整”
那真实情况会如何呢?
代码语言:javascript复制mysql> select sleep(2.8);
------------
| sleep(2.8) |
------------
| 0 |
------------
1 row in set (2.80 sec)
mysql> select sleep(2);
----------
| sleep(2) |
----------
| 0 |
----------
1 row in set (2.00 sec)
mysql> select sleep(3);
----------
| sleep(3) |
----------
| 0 |
----------
1 row in set (3.00 sec)
真实情况是,MySQL可以做的精确到对应的时间,而不是谣言中所说的只能是整数。
而且MySQL8.0版本依旧如此:
3. 误区三
当一个表tb1中有2条数据,那么以下SQL的运行结果会是如何?
代码语言:javascript复制 select a.*,sleep(2) from tb1 a
误区结果:a表的记录,总共耗时大约2s(查询a表的时间加上休眠的2s)
而实际结果是:
代码语言:javascript复制mysql> select a.*,sleep(2) from tb1 a;
---- --------------------- --------------------- ----------
| id | ts | dt | sleep(2) |
---- --------------------- --------------------- ----------
| 1 | 2038-01-01 00:00:00 | 2038-01-01 00:00:00 | 0 |
| 2 | 2038-01-01 00:00:00 | 2039-01-01 00:00:00 | 0 |
---- --------------------- --------------------- ----------
2 rows in set (4.00 sec)
耗时4s,也就是 记录数*休眠时间。
TIPS:
如果一个表中的记录数很大,而误写成此情况的SQL将一直阻塞从而造成不必要的灾难。
注:以上是与研发沟通时发现的大家对此函数的误解,其实还有很多情况也有此类误解,因此建议大家一定要亲自验证,以免以讹传讹。