資料表取樣

資料表取樣功能可讓您查詢大型 BigQuery 資料表中的隨機資料子集。取樣功能會傳回多種記錄,同時避免在掃描及處理整個資料表時產生相關的費用。

使用資料表取樣

如要在查詢中使用表格取樣,請加入 TABLESAMPLE 子句。舉例來說,下列查詢會選取資料表約 10% 的資料:

SELECT * FROM dataset.my_table TABLESAMPLE SYSTEM (10 PERCENT)

LIMIT 子句不同,TABLESAMPLE 會傳回資料表中的隨機資料子集。此外,BigQuery 不會快取包含 TABLESAMPLE 子句的查詢結果,因此查詢每次可能會傳回不同的結果。

您可以將 TABLESAMPLE 子句與其他選取條件結合使用。以下範例會對資料表的 50% 進行取樣,然後套用 WHERE 子句:

SELECT *
FROM dataset.my_table TABLESAMPLE SYSTEM (50 PERCENT)
WHERE customer_id = 1

以下範例將 TABLESAMPLE 子句與 JOIN 子句合併:

SELECT *
FROM dataset.table1 T1 TABLESAMPLE SYSTEM (10 PERCENT)
JOIN dataset.table2 T2 TABLESAMPLE SYSTEM (20 PERCENT) USING (customer_id)

如果是較小的表格,如果您彙整兩個樣本,且所有樣本資料列都未符合彙整條件,則可能會收到空白結果。

您可以將百分比指定為查詢參數。下一個範例說明如何使用 bq 指令列工具,將百分比傳遞至查詢:

bq query --use_legacy_sql=false --parameter=percent:INT64:29 \
    'SELECT * FROM `dataset.my_table` TABLESAMPLE SYSTEM (@percent PERCENT)`

BigQuery 資料表會整理成資料區塊。TABLESAMPLE 子句的運作方式是隨機從資料表中選取一定百分比的資料區塊,然後讀取所選區塊中的所有資料列。取樣精細程度受資料區塊數量限制。

通常,如果資料表或資料表分區的大小超過 1 GB,BigQuery 就會將其分割成區塊。較小的資料表可能只包含一個資料區塊。在這種情況下,TABLESAMPLE 子句會讀取整個資料表。如果取樣百分比大於零,且資料表不為空白,則資料表取樣一律會傳回部分結果。

區塊的大小可能不同,因此所選取的資料列確切比例可能會有所差異。如果您想取樣個別資料列,而非資料區塊,則可以改用 WHERE rand() < K 子句。不過,這種方法需要 BigQuery 掃描整個資料表。如要節省成本,但仍能享有資料列層級取樣的好處,您可以結合這兩種技術。

以下範例會從儲存空間讀取約 20% 的資料區塊,然後隨機選取這些區塊中的 10% 列:

SELECT * FROM dataset.my_table TABLESAMPLE SYSTEM (20 PERCENT)
WHERE rand() < 0.1

外部資料表

您可以將 TABLESAMPLE 子句與在檔案集合中儲存資料的外部資料表搭配使用。BigQuery 會對資料表參照的部分外部檔案進行取樣。對於某些檔案格式,BigQuery 可以將個別檔案拆分為區塊,以便進行取樣。某些外部資料 (例如 Google 試算表中的資料) 由單一檔案組成,並以一個資料區塊的形式進行取樣。

從寫入最佳化儲存空間進行取樣

如果您將表格取樣功能與串流插入功能搭配使用,BigQuery 會從針對寫入作業最佳化的儲存空間中取樣資料。在某些情況下,寫入最佳化儲存空間中的所有資料都會以單一區塊表示。發生這種情況時,結果中會顯示寫入最佳化儲存空間中的所有資料,或是完全不顯示。

分區和分群資料表

區隔和群組化會產生區塊,其中特定區塊內的所有資料列都具有相同的區隔鍵,或具有相近值的群組化屬性。因此,相較於未分區且未叢集的資料表,這些資料表的樣本集合往往會出現較大的偏差。

限制

  • 一個查詢陳述式只能出現一個取樣表格。這項限制包括在檢視表定義中參照的資料表。
  • 不支援從檢視表取樣資料。
  • 系統不支援對子查詢或資料表值函式呼叫的結果進行取樣。
  • 系統不支援從陣列掃描作業中進行取樣,例如呼叫 UNNEST 運算子的結果。
  • 系統不支援在 IN 子查詢中進行取樣。
  • 系統不支援從已套用資料列層級安全防護機制的資料表中進行取樣。

資料表取樣價格

如果您使用以量計價,系統會根據您讀取的資料量向您收費。BigQuery 不會快取包含 TABLESAMPLE 子句的查詢結果,因此每次執行都會產生從儲存空間讀取資料的費用。