資料表取樣

資料表取樣功能可讓您查詢大型 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 子句的查詢結果,因此每次執行都會產生從儲存空間讀取資料的費用。