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

MySQL ORDER BY RAND() 效率優化:JOIN 子查詢實測 0.0015s/次

     編輯:MySQL 資料庫相關知識

15 萬行表 ORDER BY RAND() LIMIT 5 耗時 8 秒+,官方文檔明確不建議在 ORDER BY 中使用 RAND()。經多輪優化,JOIN 子查詢方案穩定在 **0.0015 秒/次**。

優化演進路徑

  1. 原始:SELECT * FROM t ORDER BY RAND() LIMIT 1 → 8s+
  2. MAX(id)*RAND() 子查詢:WHERE id >= (SELECT FLOOR(MAX(id)*RAND()) FROM t) → 0.5s
  3. 補 MIN(id) 邊界:WHERE id >= (SELECT FLOOR(RAND()*(MAX-MIN)+MIN) FROM t) → 0.01s
  4. JOIN 重寫(最終版):見下方 → **0.0015s**

最終推薦語句(單行隨機)

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

PHP 10 次循環壓測

方案總耗時平均/次
WHERE 子查詢0.147s0.015s
JOIN 子查詢0.015s0.0015s

適用條件與變通

  • 表有自增主鍵 id,且 ID 分布相對連續(大量刪除導致空洞會降低命中率)。
  • 極大空洞表:先 SELECT id FROM t ORDER BY RAND() LIMIT 1 取隨機 ID,再 SELECT * FROM t WHERE id=? 回表。
  • 需多行隨機:循環調用上述單行語句,或改 LIMIT N 並接受連續分布特性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved