持續性 materialized view 查詢
如要建立 Bigtable 資料表的持續性具體化檢視,請執行定義該檢視的 SQL 查詢。
本文說明相關概念和模式,協助您準備持續性具體化檢視區塊的 SQL 查詢。閱讀本文之前,請先熟悉持續具體化檢視區塊和 Bigtable 適用的 GoogleSQL。
持續性具體化檢視表使用受限的 SQL 語法。以下模式說明如何建構持續性具體化檢視區塊 SQL 查詢:
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
GROUP BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
如要將持續性具體化檢視表 SQL 查詢建構為全域次要索引,請使用 ORDER BY
子句:
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
ORDER BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
查詢限制
下列規則適用於用來建立持續性 materialized view 的 SQL 查詢:
- 必須是
SELECT
陳述式。 - 必須有
GROUP BY
子句,或 (如果是全域次要索引查詢)ORDER BY
子句,但不得同時有兩者。 - 只能使用支援的匯總函式。
- 每個群組可有多個匯總。
支援的匯總
在定義連續具體化檢視表的 SQL 查詢中,您可以使用下列匯總函式:
COUNT
SUM
MIN
MAX
HLL_COUNT.INIT
HLL_COUNT.MERGE
HLL_COUNT.MERGE_PARTIAL
ANY_VALUE
BIT_AND
BIT_OR
BIT_XOR
AVG
如果 SELECT COUNT(*)
,您必須定義資料列鍵,如下列範例所示:
SELECT
'*' AS _key,
COUNT(*) AS count
FROM
foo
GROUP BY
_key;
不支援的 SQL 功能
您無法使用下列 SQL 功能:
- Bigtable 適用的 GoogleSQL 不支援的任何功能
ARRAY
ARRAY_AGG
ARRAY_CONCAT_AGG
COUNT_IF
CURRENT_TIME
和其他非確定性函式DATE
、DATETIME
做為輸出資料欄 (使用TIMESTAMP
或儲存字串)。DESC
輸出內容中的排序方式DISTINCT
選項,如SUM(*DISTINCT* value)
)LIMIT/OFFSET
SELECT *
OVER
子句,建立視窗匯總STRUCT
您也無法巢狀化 GROUP BY
或 ORDER BY
子句,或是建立地圖資料欄。如需其他限制,請參閱「限制」一節。
避免排除的資料列
在下列情況下,輸入資料列會從持續性 materialized view 中排除:
- 從資料列選取超過 1 MiB 的資料。舉例來說,如果查詢是
SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples
,則apple
和banana
資料欄中含有超過 1 MiB 資料的任何資料列,都會從連續具體化檢視區塊中排除。 - 資料列輸出超過 1 MiB 的資料。使用
SELECT REPEAT(apple, 1000)
等查詢或大型常數時,可能會發生這種情況。 - 輸出資料量是所選資料量的 10 倍以上。
- 查詢與資料不符。包括嘗試除以零、整數溢位,或預期使用並非每個資料列索引鍵都採用的資料列索引鍵格式。
系統首次處理排除的資料列時,使用者錯誤指標會增加。如要進一步瞭解可協助您監控持續具體化檢視區塊的指標,請參閱「指標」。
查詢詳細資料
本節說明持續性具體化檢視查詢,以及查詢檢視區塊時的結果可能樣貌。來源資料表中的資料是輸入內容,而持續具體化檢視中的結果資料則是輸出內容。輸出資料會經過匯總或未經匯總 (在定義的鍵中)。
SELECT 陳述式
選取陳述式會設定連續具體化檢視表使用的資料欄和匯總。陳述式必須使用 GROUP BY
子句來彙整資料列,或使用 ORDER BY
子句建立全域次要索引。
系統不支援 SELECT *
,但支援 SELECT COUNT(*)
。
如同一般 SELECT
陳述式,您可以在一組分組資料中進行多項匯總作業。未分組的資料欄必須是匯總結果。
以下是標準 GROUP BY
SQL 匯總查詢的範例:
SELECT
myfamily["node"] AS node,
myfamily["type"] AS type,
COUNT(clicks) AS clicks_per_key
FROM
mytable
GROUP BY
node,
type
資料列鍵和未經匯總的資料
您可以指定 _key
做為連續具體化檢視區塊的資料列鍵。如果沒有,GROUP BY
子句中的資料欄會形成檢視區塊中的鍵。
由 _key
欄定義的資料列鍵
定義連續具體化檢視時,您可以選擇指定 _key
欄。(這與您在 Bigtable 資料表上執行 SQL 查詢時取得的_key
資料欄不同)。如果您指定 _key
,請遵守下列規則:
- 您必須依
_key
分組,且只能依_timestamp
(選用) 分組。詳情請參閱「時間戳記」。 _key
欄必須是BYTES
類型。
如果您打算使用 ReadRows
(而非 SQL) 讀取檢視區塊,指定 _key
就很有用,因為這樣您就能控管資料列鍵格式。另一方面,如果檢視表的 SQL 查詢已定義 _key
,則可能需要明確解碼 _key
,而不是只傳回結構化鍵資料欄。
由 GROUP BY
或 ORDER BY
子句定義的資料列索引鍵
如未指定 _key
,SELECT
清單中未匯總的資料欄就會成為檢視畫面中的資料列鍵。您可以為鍵資料欄指派 SQL 慣例支援的任何名稱。如果您打算使用 SQL 查詢檢視表,而非 ReadRows
請求,請採用這種做法。
SELECT
清單中的非匯總輸出資料欄必須包含在 GROUP
BY
子句中。GROUP BY
子句中寫入資料欄的順序,就是資料在連續具體化檢視資料列鍵中儲存的順序。舉例來說,GROUP BY a, b, c
會隱含 ORDER BY a ASC, b ASC, c
ASC
。
如果您使用 ORDER BY
子句 (而非 GROUP BY
子句) 建立全域次要索引,SELECT
清單中屬於 ORDER BY
子句的資料欄會成為檢視區塊中的資料列鍵。在 ORDER BY
子句中寫入資料欄的順序,就是資料在連續具體化檢視畫面資料列鍵中儲存的順序。舉例來說,ORDER BY a, b, c
會依資料列索引鍵的順序儲存資料,先是 a ASC
,然後是 b ASC
,最後是 c ASC
。
SQL 篩選器必須排除可能導致錯誤的 NULL
或其他無效值。系統會從結果中省略無效資料列 (例如包含 NULL
鍵資料欄的資料列),並計入 materialized_view/user_errors
指標。如要偵錯使用者錯誤,請嘗試在連續具體化檢視區塊外執行 SQL 查詢。
匯總資料
查詢中的匯總資料欄會定義產生持續性具體化檢視中資料的計算。
匯總資料欄的別名在連續具體化檢視中會視為資料欄限定符。
請見如下範例:
SELECT
fam["baz"] AS baz,
SUM(fam["foo"]) AS sum_foo,
SUM(fam["bar"]) AS sum_bar
FROM
TABLE
GROUP BY
baz;
查詢輸出內容具有下列特徵:
- 每個
baz
的輸出內容會依baz ASC
順序顯示在不同資料列中。 - 如果指定
baz
至少有一個foo
,則輸出資料列的sum_foo
為非空值。 - 如果指定
baz
至少有一個bar
,則輸出資料列的sum_bar
為非空值。 - 如果指定
baz
的任一欄位沒有值,系統會從結果中省略該baz
。
接著,如果您使用 SELECT *
查詢檢視區塊,結果會類似下列內容:
baz | sum_foo | sum_bar |
---|---|---|
baz1 | sum_foo1 | sum_bar1 |
baz2 | sum_foo2 | sum_bar2 |
時間戳記
持續具體化檢視表中輸出儲存格的預設時間戳記為 0 (1970-01-01 00:00:00Z
)。使用 ReadRows
讀取檢視表時會看到這個時間戳記,但使用 SQL 查詢時不會。
如要在輸出中使用不同的時間戳記,您可以將 TIMESTAMP
類型的資料欄新增至查詢的 SELECT
清單,並將其命名為 _timestamp
。如果您使用 ReadRows
查詢連續具體化檢視表,_timestamp
會成為該資料列中其他儲存格的時間戳記。
時間戳記不得為 NULL
,必須大於或等於零,且必須是 1,000 的倍數 (精確度為毫秒)。Bigtable 不支援早於 Unix 紀元 (1970-01-01T00:00:00Z) 的儲存格時間戳記。
請看以下範例,瞭解如何依天重新取樣匯總資料。查詢會使用 UNPACK
函式。
SELECT
_key,
TIMESTAMP_TRUNC(_timestamp, DAY) AS _timestamp,
SUM(sum_family["sum_column"]) AS sum_column,
SUM(sum_family["foo"]) AS second_sum_column
FROM
UNPACK(
SELECT
*
FROM
my_table(with_history => TRUE))
GROUP BY
1,
2
如果指定 SUM
在特定日期有非空白的輸入內容,則輸出資料列會包含匯總值,以及與截斷日期相符的時間戳記。
如果您使用 SELECT *
查詢檢視區塊,結果會類似下列內容:
_key | _timestamp | sum_column | second_sum_column |
---|---|---|---|
1 | 2024-05-01 00:00:00Z | 23 | 99 |
2 | 2024-05-02 00:00:00Z | 45 | 201 |
3 | 2024-05-03 00:00:00Z | 空值 | 56 |
4 | 2024-05-04 00:00:00Z | 8 | 空值 |
編碼
如果您使用 SQL 查詢持續性具體化檢視區塊,則不需要瞭解匯總值的編碼方式,因為 SQL 會將結果顯示為已輸入的資料欄。
如果使用 ReadRows
從檢視區塊讀取資料,您需要在讀取要求中解碼匯總資料。如要進一步瞭解 ReadRows
請求,請參閱「讀取」。
系統會根據檢視定義中資料欄的輸出類型,使用下表所述的編碼方式,儲存連續具體化檢視中的匯總值。
類型 | 編碼 |
---|---|
BOOL | 1 位元組值,1 = true,0 = false |
BYTES | 無編碼 |
INT64 (或 INT、SMALLINT、INTEGER、BIGINT、TINYINT、BYTEINT) | 64 位元大端 |
FLOAT64 | 64 位元 IEEE 754,不含 NaN 和 +/-inf |
STRING | UTF-8 |
TIME/TIMESTAMP | 64 位元整數,代表自 Unix 紀元起算的微秒數 (與 GoogleSQL 一致) |