MySQL的bug:子查詢中使用rand(),上層查詢中rand()的值被重算
阿新 • • 發佈:2019-01-23
在使用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版本,都會出現這個問題。
那個人也發現,當子查詢中有rand()時,每次引用到rand()都會重算一次,如下圖。
但是這個bug單,官方似乎不以為意,已經一年多沒人回覆了。只是MySQL的高階首席工程師Roy Lyseng在結尾提出了權衡的解決方案:對於5.7的版本,在子查詢中加上limit,這個問題就可以解決了。對於8.0及以上的版本,可以使用NO_MERGE特性來解決這個問題。