關聯式資料庫預設無序,需引入隨機排序機制。大表全表排序代價高昂,各資料庫提供不同語法與效能特性。
| 資料庫 | 語法範例 (取 20 筆) | 機制說明 | 效能備註 |
|---|---|---|---|
| SQL Server | SELECT TOP 20 * FROM 表 ORDER BY NEWID(); | NEWID() 產生 GUID 排序 | 全表掃描 + 排序,大表極慢;建議配合 TABLESAMPLE (近似抽樣) 或主鍵範圍隨機 |
| Access | SELECT TOP 20 * FROM 表 ORDER BY Rnd(Id); | Rnd(數值欄位) 產生偽隨機數 | 同樣全表排序;Id 可為任何數值/自動編號欄位 |
| MySQL | SELECT * FROM 表 ORDER BY RAND() LIMIT 20; | RAND() 每列產生 0~1 浮點數排序 | 全表排序,大表災難;優化見下文 |
| PostgreSQL | SELECT * FROM 表 ORDER BY RANDOM() LIMIT 20; | RANDOM() 同 MySQL | 同樣全表排序;支援 TABLESAMPLE BERNOULLI/SYSTEM |
| Oracle | SELECT * FROM (SELECT * FROM 表 ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 20; | DBMS_RANDOM.VALUE 產生隨機值 | 全表排序;12c+ 支援 SAMPLE 子句 |
| DB2 | SELECT * FROM 表 ORDER BY RAND() FETCH FIRST 20 ROWS ONLY; | RAND() 標量函數 | 全表排序;支援 TABLESAMPLE |
-- SQL Server (資料頁層級抽樣,非逐列)
SELECT * FROM 表 TABLESAMPLE (10 PERCENT) REPEATABLE (12345);
-- PostgreSQL
SELECT * FROM 表 TABLESAMPLE BERNOULLI (10) REPEATABLE (12345);
-- Oracle 12c+
SELECT * FROM 表 SAMPLE (10);
REPEATABLE 種子可復現。-- 取得 PK 範圍
DECLARE @MinID INT, @MaxID INT, @RandomID INT;
SELECT @MinID = MIN(Id), @MaxID = MAX(Id) FROM 表;
SET @RandomID = @MinID + CAST(RAND() * (@MaxID - @MinID) AS INT);
-- 取大於等於隨機 ID 的前 N 筆 (需 PK 索引)
SELECT TOP 20 * FROM 表 WHERE Id >= @RandomID ORDER BY Id;
NEWID() 多次隨機起點取樣並 UNION 去重。利用 sys.dm_db_stats_histogram 統計直方圖步驟值作為隨機起點,提升代表性。
ORDER BY RAND()/NEWID() 簡單可行。REPEATABLE 種子確保可重現性。