15 萬條資料 ORDER BY RAND() LIMIT 5 耗時 8 秒+,經優化降至 0.01 秒。核心思路:**避免全表掃描與多次 RAND() 計算,改用主鍵範圍隨機定位**。
SELECT * FROM tablename ORDER BY RAND() LIMIT 1;
官方文檔明確不建議:ORDER BY 子句會多次評估 RAND(),導致多次全表掃描。
SELECT * FROM `table` AS t1
JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 5;
問題:產生連續 5 條;若 ID 不從 1 起,概率偏向前段資料。
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;
SELECT * FROM `table`
WHERE id >= (
SELECT FLOOR(
RAND() * ((SELECT MAX(id) FROM `table`) - (SELECT MIN(id) FROM `table`))
+ (SELECT MIN(id) FROM `table`)
)
)
ORDER BY id LIMIT 1;
MIN(id)、MAX(id) 界定隨機範圍JOIN 而非 WHERE 子查詢