15 萬行表 ORDER BY RAND() LIMIT 5 耗時 8 秒+,官方文檔明確不建議在 ORDER BY 中使用 RAND()。經多輪優化,JOIN 子查詢方案穩定在 **0.0015 秒/次**。
SELECT * FROM t ORDER BY RAND() LIMIT 1 → 8s+WHERE id >= (SELECT FLOOR(MAX(id)*RAND()) FROM t) → 0.5sWHERE id >= (SELECT FLOOR(RAND()*(MAX-MIN)+MIN) FROM t) → 0.01sSELECT *
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;
| 方案 | 總耗時 | 平均/次 |
|---|---|---|
| WHERE 子查詢 | 0.147s | 0.015s |
| JOIN 子查詢 | 0.015s | 0.0015s |
id,且 ID 分布相對連續(大量刪除導致空洞會降低命中率)。SELECT id FROM t ORDER BY RAND() LIMIT 1 取隨機 ID,再 SELECT * FROM t WHERE id=? 回表。LIMIT N 並接受連續分布特性。