技術分享 | 使用 RAND() 函數過程中發現的詭異 Bug 分析

2021-12-10 愛可生開源社區

作者:Agate Li

愛可生研發團隊成員,負責資料庫管理平臺相關項目,.Net 技術愛好者,長期潛水於技術圈。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。

背景

MySQL 中的 RAND() 函數是一個隨機數發生器,可以返回一個 >=0 並 <1.0 的隨機浮點數。最近在實際使用過程裡遇見了一個主流版本中非常詭異的 Bug,故整理出來,以免大家踩坑。文中使用的 MySQL 版本是 5.7.25,話不多說,直接上演示:

1. 創建測試表

CREATE TABLE test (`id` INT(3) NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=`InnoDB`;

INSERT INTO test VALUES(),(),(),(),(),(),(),(),(),();

3. 關鍵來了,執行幾次下面這條 SQL

SELECT sub.rnd FROM (SELECT FLOOR(RAND()*10) rnd FROM test) sub WHERE sub.rnd<3;

明明指定了篩選內層 sub.rnd 小於 3 的條件,輸出出來的結果卻完全不對。

4. 接下來排查問題的觸發條件

由於直接使用 RAND() 函數輸出出來的結果是隨機的,首先要做的就是指定一枚固定的種子,一是以免幹擾後續排查,二是可以讓大家自行精確復現。

仍然符合預期,看起來不像是 RAND() 函數本身的問題。

5. 為第三步中的 SQL 指定種子:

SELECT sub.rnd FROM (SELECT FLOOR(RAND(100)*10) rnd FROM test) sub WHERE sub.rnd<3;

熟悉的味道出現了,刺激的感覺回來了…… EXPLAIN 一波

6. 去掉第三步中的 test 表再試

SELECT sub.rnd FROM (SELECT FLOOR(RAND(100)*10) rnd) sub WHERE sub.rnd<3;

7. 再改改第三步中的 SQL

SELECT sub.rnd FROM (SELECT FLOOR(RAND(100)*10) rnd FROM test LIMIT 10000) sub WHERE sub.rnd<3;

8. 再驗證一次,把第三步中的 SQL 拉平

SELECT FLOOR(RAND(100)*10) rnd FROM test HAVING rnd<3;

9. 這時候可以推測,大概率是在派生表未物化的情況下 RAND() 在外層重算了……

拿著推測,去 google 一波,立刻找到了一個相關 Bug:

https://bugs.mysql.com/bug.php?id=86624

嗯,2017 年年中就有人報過的 Bug,再看看 Bug 狀態,噢,「嘻嘻,我們驗證了但不打算修」……

好在官方還是給出了解決方法:

對於5.7,跟我們的做法一樣,加上 LIMIT <一個很大的數>;

 點一下「閱讀原文」了解更多資訊

相關焦點

  • Excel產生隨機數Rand函數巧妙應用
    Excel中產生隨機數的函數有兩個,一個是rand函數,一個是randbetween函數,今天主要介紹rand函數的用法,從入門至精通。
  • GBA(Golden Bug Award)
    1、我們內部每兩個月定期組織一次評選2、參賽選手需要從以下五個方面來描述缺陷:-缺陷的主題描述-缺陷的影響分析-缺陷的發現過程-缺陷的解決方法-測試技術或方法傳承3、評委通過四個維度來進行打分-缺陷發現的難易程度-測試技術/方法的創新性
  • 【Excel技巧】有了這兩個隨機函數rand和randbetween,要怎麼隨機都可以
    RAND函數和RANDBETWEEN函數。別小看這兩個函數,它們雖是小函數,但有大能量。因為它們為我們隨機錄入批量數據提供了很大方便。一、Rand函數用途:用於生成0~1之間的隨機數。語法結構:=RAND()現在看看rand怎麼生成0~1之間的隨機數,如下:現在再看看rand怎麼生成1~10的隨機整數,公式:=
  • 使用Listagg分析函數優化wmsys.wm_concat
    該執行計劃中全是HASH JOIN,我就不貼了。大家看我分析思路:1. 首先這SQL最終返回20779行數據,該SQL語句最後部分沒有GROUP BY,僅僅是表關聯,並且是外連接2. 那麼我可以判定zh也就差不多20779行數據,因為它是外連接的主表3.
  • 原創 分享兩本技術分析入門經典著作
    3月11日報告會結束時,我給大家推薦了兩本技術分析經典書籍。會後,有朋友說沒記下來,今天給大家做個介紹。
  • 數據處理過程中常用的excel函數:IF、COUNTIF
    包括如何調用函數以及在函數使用過程當中需要注意的引用問題。今天我們就來介紹幾個常用的excel函數。今天就來介紹一下: IF函數以及countif函數關於excel函數都有固定的輸入形式,我們只需要按照固定的位置輸入想要的東西即可。1.
  • 它是Excel中最神秘的統計函數,Frequency函數的使用方法
    Excel用戶中,能了解frequency函數用法的人很少,因為這個函數教程少,理解起來有點困難。
  • 使用VLOOKUP函數從不同工作表中提取數據
    在Excel中,運用查找函數是excel中進行數據統計分析最常用的操作之一,VLOOKUP函數是EXCEL中最常用的查找函數,該函數的語法規則如下
  • Excel中Lookup函數使用大全!附案例詳解!
    職場中,經常會使用vlookup函數。
  • FIND函數使用方法
    FIND函數使用方法導讀EXCEL函數是重點部分,也是比較難學的部分,很多同學因為它的難度選擇了放棄,其實函數也沒有想像的那麼難
  • Excel:RAND隨機類函數
    Excel 中隨機類函數常用於產生隨機數。隨機數可廣泛用於各類抽獎、抽查及分類分組等活動中。
  • Excel | INDEX、RANDBETWEEN、RAND函數隨機分組
    點擊上方"韓老師講Office"關注,歡迎分享問題來源某公司對應聘面試者進行分組
  • Oracle之CASE函數使用
    Oracle之CASE函數使用前面我們從不同維度去分析的Oracle和MySQL的區別和使用,接下來我們來分享一些Oracle的函數和特殊用法。
  • Excel | 如何使用COUNTIFS函數
    COUNTIF函數僅能使用一個條件來進行計數。       COUNTIFS函數是多條件進行計數。
  • excel中if函數嵌套式使用教程
    嵌套if函數使用步驟2:輸入公式=IF(E2="","需補考",IF(E2<60,"不合格",IF(E2<80,"合格",IF(E2<90,"良好","優秀"))))。  嵌套if函數使用步驟4:輸入公式=IF(E2="","需補考",IF(E2<60,"不合格",IF(E2<80,"合格",IF(E2<90,"良好","優秀"))))  嵌套if函數使用步驟5:語句解釋
  • 用簡單的分析發現運營的秘密之交叉分析
    比較對照是進行數據探索與分析的基本手段之一。對於數值型(定量)的數據,進行比較對照時可以用均數檢驗、方差分析等方法。