首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

T-SQL 隨機抽樣與分頁查詢:NEWID() 隨機排序、ROW_NUMBER() 分頁的標準寫法與性能考量

     編輯:關於SqlServer

隨機抽樣:TABLESAMPLE vs NEWID()

-- 方法 1: NEWID() 全表排序 (精確隨機、大表極慢)
SELECT TOP 5 * 
FROM Person.Address
ORDER BY NEWID();

-- 方法 2: TABLESAMPLE (頁級採樣、極快、非嚴格隨機)
SELECT * 
FROM Person.Address 
TABLESAMPLE (10 PERCENT)  -- 或 (100 ROWS)
REPEATABLE (42);  -- 固定種子可復現

分頁查詢:OFFSET/FETCH (SQL 2012+) vs ROW_NUMBER()

-- 標準語法 (SQL 2012+ 推薦)
SELECT * 
FROM Person.Address
ORDER BY City
OFFSET 49 ROWS FETCH NEXT 151 ROWS ONLY;  -- 第 50-200 行

-- 兼容寫法 (SQL 2005/2008/R2)
SELECT * 
FROM (
    SELECT *, ROW_NUMBER() OVER (ORDER BY City) AS RowNum
    FROM Person.Address
) AS t
WHERE t.RowNum BETWEEN 50 AND 200;

性能對比與選擇指南

場景推薦方案理由
小表 (<1萬行) 隨機抽樣ORDER BY NEWID()簡單精確
大表 隨機抽樣TABLESAMPLE / BERNOULLI避免全表排序
分頁查詢 (SQL 2012+)OFFSET/FETCH語法清晰、優化器友好
分頁查詢 (舊版本)ROW_NUMBER() CTE標準兼容
深分頁 (第 10萬頁)Keyset Pagination (Seek 法)避免掃描大量前置行

Keyset Pagination (游標分頁) 高性能模式

-- 首頁
SELECT TOP 50 * FROM Person.Address ORDER BY City, AddressID;

-- 後續頁 (記住上一頁最後一行的排序鍵值)
DECLARE @LastCity NVARCHAR(30) = '...', @LastID INT = ...;
SELECT TOP 50 * 
FROM Person.Address
WHERE City > @LastCity OR (City = @LastCity AND AddressID > @LastID)
ORDER BY City, AddressID;

總結

  • NEWID() 適合小數據集精確隨機
  • TABLESAMPLE 適合大表統計抽樣
  • 分頁優先用 OFFSET/FETCH,深分頁必須用 Keyset 分頁
  • 所有排序列必須有確定順序 (加唯一鍵防抖動)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved