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 整數
SELECT * FROM t ORDER BY RAND() LIMIT 5;
-- 15 萬表,查 5 行耗 8 秒+
-- 原因:全表掃描 + 生成隨機數 + 檔案排序 + LIMIT
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 行
SELECT * FROM t
WHERE id >= (SELECT FLOOR(MAX(id) * RAND()) FROM t)
ORDER BY id LIMIT 1;
-- 0.5 秒
SELECT * FROM t
WHERE id >= (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM t)))
ORDER BY id LIMIT 1;
-- 0.01 秒
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;
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;
| 方案 | 總耗時(秒) | 單次均值(毫秒) |
|---|---|---|
| 子查詢版(第 3/4 代) | 0.147 | 14.7 |
| JOIN 版(終極版) | 0.015 | 1.5 |
需求:產生 [x, y] 區間隨機整數
ROUND(RAND() * (y - x) + x)
-- 推導:
-- RAND() ∈ [0,1]
-- RAND() * (y-x) ∈ [0, y-x]
-- + x → [x, y]
-- ROUND 四捨五入取整
FLOOR(RAND() * N) 產生整數RAND(seed) 固定種子RAND() 好用但危險,掌握邊界與替代方案,才能在生產環境安心使用。