業務常需從大表中隨機抽取 N 條記錄用於測試、抽獎、審計抽查等場景。Access 與 SQL Server 因底層引擎差異,實現語法截然不同,本文對比兩種方案並給出性能建議。
SELECT TOP n * FROM TableName ORDER BY Rnd(ID)
ID 必須為自動編號(Long 類型)主鍵,Rnd() 以此為種子生成偽隨機序列。Rnd([PrimaryKey] * Timer()) 增加熵源。Rnd() 再排序,百萬級表極慢,且隨機分布質量一般。SELECT TOP n * FROM TableName ORDER BY NEWID()
NEWID() 生成全局唯一標識符(GUID),每行調用產生不同值,天然隨機分布均勻。-- 按頁面抽樣 10%,極快但非精確行級隨機
SELECT * FROM TableName TABLESAMPLE (10 PERCENT)
-- 指定行數近似(需配合 TOP)
SELECT TOP 100 * FROM TableName TABLESAMPLE (1000 ROWS)
DECLARE @minID BIGINT, @maxID BIGINT, @randomID BIGINT;
SELECT @minID = MIN(ID), @maxID = MAX(ID) FROM LargeTable;
-- 生成隨機主鍵值(假設 ID 連續或近似連續)
SET @randomID = @minID + CAST(RAND() * (@maxID - @minID) AS BIGINT);
-- 索引 Seek 定位單行(或配合 TOP N 向後掃描)
SELECT TOP 10 * FROM LargeTable WHERE ID >= @randomID ORDER BY ID;
RAND() 計算極快,SEEK 定位 O(log N)。RandomSort INT 列,建立非聚簇索引。UPDATE LargeTable SET RandomSort = CAST(RAND() * 2147483647 AS INT)。SELECT TOP n * FROM LargeTable ORDER BY RandomSort — 索引順掃,無排序開銷。| 方案 | 耗時 | 隨機質量 | 適用場景 |
|---|---|---|---|
| ORDER BY NEWID() | 120 秒 | 優 | 萬級以下、一次性任務 |
| TABLESAMPLE (1 PERCENT) | 50 毫秒 | 一般(頁面聚類) | 大表快速預覽、近似統計 |
| 主鍵範圍 RAND() | 3 毫秒 | 良(依賴 ID 分布) | 高頻單行/少量行隨機讀取 |
| 預計算 RandomSort | 2 毫秒 | 優 | 高頻固定比例抽樣、A/B 測試分桶 |
ORDER BY Rnd(ID),簡單可維護。ORDER BY NEWID() 最省事。RandomSort 列 + 索引,或主鍵範圍 RAND()(ID 連續時)。TABLESAMPLE 配合專業統計工具(R/Python)後處理。核心原則:避免全表排序。隨機抽樣本質是「不按業務順序讀取」,利用索引有序性或預計算將隨機性轉化為順序讀取,是性能突破的關鍵。