首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL RAND() 函數隨機數生成實戰:UPDATE 批量隨機值、ORDER BY RAND() 陷阱與高效隨機採樣 4 代演進

     編輯:MySQL 資料庫相關知識

MySQL RAND() 回傳 0-1 浮點數,廣泛用於測試資料生成、隨機採樣。本文涵蓋:UPDATE 批量賦隨機值、ORDER BY RAND() 效能陷阱、高效隨機採樣 4 代演進與 PHP 壓測數據。

一、批量更新隨機值

UPDATE cdb_posts SET views = RAND();  -- 0-1 浮點數
UPDATE cdb_posts SET views = FLOOR(RAND() * 10000);  -- 0-9999 整數

二、ORDER BY RAND() 陷阱

SELECT * FROM t ORDER BY RAND() LIMIT 5;
-- 15 萬表,查 5 行耗 8 秒+
-- 原因:全表掃描 + 生成隨機數 + 檔案排序 + LIMIT

三、高效隨機採樣 4 代演進

第 1 代:JOIN + MAX(id) * RAND()

SELECT * FROM t AS t1
JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM t)) AS id) AS t2
WHERE t1.id >= t2.id ORDER BY t1.id ASC LIMIT 5;
-- 產生連續 5 行

第 2 代:子查詢 + FLOOR(MAX * RAND())

SELECT * FROM t
WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM t)
ORDER BY id LIMIT 1;
-- 0.5 秒

第 3 代:內聯子查詢(去掉外層 MAX)

SELECT * FROM t
WHERE id >= (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM t)))
ORDER BY id LIMIT 1;
-- 0.01 秒

第 4 代:加 MIN(id) 修正分佈偏移

SELECT * FROM t
WHERE id >= (
  SELECT FLOOR(
    RAND() * ((SELECT MAX(id) FROM t) - (SELECT MIN(id) FROM t))
    + (SELECT MIN(id) FROM t)
  )
)
ORDER BY id LIMIT 1;

終極穩定版:JOIN 形式

SELECT * FROM t AS t1
JOIN (
  SELECT ROUND(
    RAND() * ((SELECT MAX(id) FROM t) - (SELECT MIN(id) FROM t))
    + (SELECT MIN(id) FROM t)
  ) AS id
) AS t2
WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 1;

四、PHP 壓測 10 次對比

方案總耗時(秒)單次均值(毫秒)
子查詢版(第 3/4 代)0.14714.7
JOIN 版(終極版)0.0151.5

五、指定範圍隨機整數公式

需求:產生 [x, y] 區間隨機整數

ROUND(RAND() * (y - x) + x)
-- 推導:
-- RAND() ∈ [0,1]
-- RAND() * (y-x) ∈ [0, y-x]
-- + x → [x, y]
-- ROUND 四捨五入取整

六、最佳實踐清單

  • 大表隨機採樣:**禁用 ORDER BY RAND()**
  • 主鍵連續/近似連續 → **JOIN + RAND() * (MAX-MIN) + MIN**
  • 主鍵稀疏/有洞 → 應用層預取 ID 列表隨機抽樣
  • 批量更新隨機值:FLOOR(RAND() * N) 產生整數
  • 可重現測試:RAND(seed) 固定種子

RAND() 好用但危險,掌握邊界與替代方案,才能在生產環境安心使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved