使用 TABLESAMPLE 限制結果集

TABLESAMPLE 子句會將 FROM 子句中資料表所傳回的資料列數限制為取樣數目或是資料列的 PERCENT。例如:

TABLESAMPLE (10 PERCENT) /*Return a sample 10 percent of the rows of the result set. */
TABLESAMPLE (15 ROWS) /* Return a sample of 15 rows from the result set. */.

TABLESAMPLE 不能套用至衍生資料表、連結的伺服器之資料表以及從資料表值函式、資料列集函數或是 OPENXML 所衍生的資料表。TABLESAMPLE 無法在檢視的定義中或是在嵌入資料表值函式中指定。

TABLESPACE 子句的語法如下:

TABLESAMPLE [SYSTEM] (sample_number [ PERCENT | ROWS ] )

[ REPEATABLE (repeat_seed) ]

[!附註]

TABLESAMPLE 已在 SQL Server 2005 中推出。當您針對從舊版升級的資料庫使用 TABLESAMPLE 時,資料庫的相容性層級至少必須設定為 90。若要設定資料庫相容性層級,請參閱<ALTER DATABASE (Transact-SQL)>。

當下列其中一項條件成立時,就可以使用 TABLESAMPLE 快速從大型資料表傳回取樣。

  • 該取樣在個別資料列層級不需是真正的隨機取樣。

  • 在資料表個別頁面上的資料列未與相同頁面上的其他資料列相互關聯。

重要事項重要事項

如果您真的想要個別資料列的隨機取樣,請將查詢修改為隨機篩選出資料列,而不是使用 TABLESAMPLE。例如,下列查詢使用 NEWID 函數來傳回大約 Sales.SalesOrderDetail 資料表中資料列的 1%:

SELECT * FROM Sales.SalesOrderDetail

WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)

/ CAST (0x7fffffff AS int)

SalesOrderID 資料行包含在 CHECKSUM 運算式中,可讓 NEWID() 針對每個資料列評估一次,以達成為每個資料列取樣的目標。運算式 CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS int) 會評估成介於 0 到 1 之間的隨機 float 值。

使用 SYSTEM 選項

SYSTEM 可指定 ANSI SQL 實作相依的取樣方法。指定 SYSTEM 雖然是選擇性的,但此選項卻是 SQL Server 中唯一可使用的取樣方法,而且預設會套用它。

TABLESAMPLE SYSTEM 會傳回資料列數的近似百分比,並會為資料表中每 8 KB 的實體頁產生隨機值。根據某頁中的隨機值以及查詢中所指定的百分比,在取樣中包含或排除某頁。所包含的每頁會傳回取樣結果集中的所有資料列。例如,當指定 TABLESAMPLE SYSTEM 10 PERCENT 時,SQL Server 會傳回資料表之指定資料頁約 10% 的資料列。如果資料列平均分配在資料表的各頁上,而且如果資料表中有足夠的頁數,則傳回的資料列數目應該近似於要求的取樣大小。然而,由於針對每頁所產生的隨機值與針對任何其他頁所產生的值無關,因此有可能會傳回比要求的百分比較大或較小的頁數百分比。TOP(n) 運算子可用以將資料列的數目限制成指定的最大值。

當指定資料列數目而不是資料表中資料列總數的百分比時,會將該數目轉換成資料列數的百分比,因此應該會傳回頁數。接著會使用該計算出的百分比來執行 TABLESAMPLE 作業。

如果資料表是由單一頁所組成,則會傳回該頁的所有資料列或是沒有任何資料列傳回。在此情況下,不論該頁的資料列數為何,TABLESAMPLE SYSTEM 都只能傳回該頁之資料列的 100% 或 0%。

對於指定資料表使用 TABLESAMPLE SYSTEM,將限制執行計畫對於該資料表使用資料表掃描 (堆積的掃描或是叢集索引 (如果有的話) 的掃描)。雖然該計畫顯示執行了資料表掃描,但只有那些包含在結果集中的頁才真正需要從資料檔中讀取它們。

重要事項重要事項

應該謹慎地使用 TABLESAMPLE SYSTEM 子句,並對使用取樣的含義有相當程度的瞭解。例如,兩個資料表的聯結有可能會同時傳回兩個資料表中每個資料列相符的資料列;然而,如果為兩個資料表的其中一個指定 TABLESAMPLE SYSTEM,則從未取樣的資料表所傳回的某些資料列就不可能有取樣資料表的相符資料列。雖然實際上資料是有效的,但這有可能會使您懷疑基礎資料表中有資料一致性的問題。同樣地,如果為聯結的兩個資料表指定 TABLESAMPLE SYSTEM,所發現的問題可能會更糟。

使用 REPEATABLE 選項

REPEATABLE 選項會再傳回一次選取的取樣。當以相同的 repeat_seed 值指定 REPEATABLE 時,只要資料表未做過任何變更,SQL Server 就會傳回相同的資料列子集。當以不同的 repeat_seed 值指定 REPEATABLE 時,SQL Server 通常會傳回資料表中資料列的不同取樣。下列對於資料表所進行的動作將視為變更:插入、更新、刪除、索引重建、索引重組、還原資料庫以及附加資料庫。

範例

A. 選取某百分比的資料列

Person.Person 資料表包含 19,972 個資料列。下列陳述式會傳回約百分之 10 的資料列。傳回的資料列數通常會隨著陳述式的每次執行而改變。

USE AdventureWorks2008R2 ;
GO
SELECT FirstName, LastName
FROM Person.Person 
TABLESAMPLE (10 PERCENT) ;

B. 以初始值選取某百分比的資料列

下列陳述式會在每次執行時傳回同一組資料列。初始值 205 是任意選擇的值。

USE AdventureWorks2008R2 ;
GO
SELECT FirstName, LastName
FROM Person.Person 
TABLESAMPLE (10 PERCENT) 
   REPEATABLE (205) ;

C. 選取數個資料列

下列陳述式會傳回約 100 個資料列。傳回的實際資料列數可能會有極大的差異。如果指定的數目較小 (例如 5),您可能無法在樣本中收到結果。

USE AdventureWorks2008R2 ;
GO
SELECT FirstName, LastName
FROM Person.Person 
TABLESAMPLE (100 ROWS) ;

請參閱

參考