需求:從資料表隨機抽取 N 筆或隨機排序全表。SQL Server 提供 NEWID() 產生唯一識別碼,配合 ORDER BY 即可實現,但大表效能陷阱需注意。
-- 隨機排序全表
SELECT * FROM Northwind..Orders ORDER BY NEWID()
-- 隨機抽取 10 筆
SELECT TOP 10 * FROM Northwind..Orders ORDER BY NEWID()
NEWID() 為每列產生一個隨機 GUID。ORDER BY NEWID() 依此 GUID 排序,達到隨機效果。RAND() 在單一查詢中僅計算一次,所有列取得相同值,不可用於隨機排序。掃描全表 → 產生計算欄 → 排序,複雜度 O(N log N),記憶體/TempDB 壓力大。
百萬列以上表執行時間可達秒級甚至分鐘級,嚴重阻塞並發。
SELECT * FROM BigTable TABLESAMPLE (10 PERCENT) -- 依頁面抽樣
-- 或
SELECT * FROM BigTable TABLESAMPLE (1000 ROWS)
DECLARE @maxID INT, @randID INT
SELECT @maxID = MAX(ID) FROM BigTable
SET @randID = @maxID * RAND() -- 應用層產生隨機數
SELECT TOP 10 * FROM BigTable WHERE ID >= @randID
-- 不足 10 筆時可 UNION ALL 從頭補齊
RandSortKey 並建立索引。ORDER BY RandSortKey,無運算開銷。| 資料量 | 推薦方案 | 備註 |
|---|---|---|
| < 10 萬列 | ORDER BY NEWID() | 簡單直觀,效能可接受 |
| 10 萬 ~ 百萬 | TABLESAMPLE + 後續精確過濾 | 平衡效能與隨機度 |
| > 百萬 | 預先隨機鍵 / PK 跳躍 | 避免全表排序 |
NEWID() 是小中型表隨機取樣的利器,但嚴禁在大表直接使用。生產環境請依資料量選擇 TABLESAMPLE、PK 跳躍或預計算隨機鍵,確保查詢穩定高效。