MySQL的bug:子查询中使用rand(),上层查询中rand()的值被重算

源:https://blog.csdn.net/huanghanqian/article/details/82899885
在使用mysql的过程中,发现了一个神奇的bug。

mysql语句如下:

select random_val from (select floor(rand()*10) as random_val from Test) b  where b.random_val <3;

其中,Test表是个无关轻重的表(毕竟并没有从里面取数据,只是得到的结果跟Test内的数据条数有关),我也展示一下它的内容吧,其实无关紧要
在这里插入图片描述
下面展示sql语句执行的奇怪之处了:
在这里插入图片描述

我在where中限制了random_val<3, 但是结果中仍然出现了random_val>=3的内容。

经验证发现,这个问题是否出现,与mysql的版本有关。版本5.6.21及以下,不会出现这个问题,而版本5.7.11以上,包括最新的8.0.11版本,都会出现这个问题。

考虑到有可能是mysql的一个bug,我去官网上查issue。发现已经有人提bug单了。https://bugs.mysql.com/bug.php?id=86624

那个人也发现,当子查询中有rand()时,每次引用到rand()都会重算一次,如下图。
在这里插入图片描述

但是这个bug单,官方似乎不以为意,已经一年多没人回复了。只是MySQL的高级首席工程师Roy Lyseng在结尾提出了权衡的解决方案:对于5.7的版本,在子查询中加上limit,这个问题就可以解决了。对于8.0及以上的版本,可以使用NO_MERGE特性来解决这个问题。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值