1. 程式人生 > >MySQL的bug:子查詢中使用rand(),上層查詢中rand()的值被重算

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

  在使用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特性來解決這個問題。