継続的マテリアライズド ビューのクエリ
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
クエリの制限事項
継続的マテリアライズド ビューの作成に使用される 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
句をネストしたり、マップ列を作成したりすることもできません。その他の制限事項については、制限事項をご覧ください。
除外された行を避ける
次のような状況では、入力行は継続的マテリアライズド ビューから除外されます。
- 行から 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 ステートメント
SELECT ステートメントは、継続的マテリアライズド ビューで使用される列と集計を構成します。ステートメントでは、GROUP BY
句を使用して行を集計するか、ORDER BY
句を使用して非同期セカンダリ インデックスを作成する必要があります。
SELECT *
はサポートされていませんが、SELECT COUNT(*)
はサポートされています。
一般的な SELECT
ステートメントと同様に、グループ化されたデータセットごとに複数の集計を行うことができます。グループ化されていない列は集計結果である必要があります。
これは、SQL の標準 GROUP BY
集計クエリの例です。
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
にする必要があります。
_key
を指定すると、SQL ではなく ReadRows
でビューを読み取る場合に便利です。行キー形式を制御できるためです。一方、_key
が定義されたビューに対する SQL クエリでは、構造化されたキー列を返すだけでなく、_key
を明示的にデコードする必要がある場合があります。
GROUP BY
句または ORDER BY
句で定義された行キー
_key
を指定しない場合、SELECT
リストの集計されていない列がビューの行キーになります。キー列には、SQL 規則でサポートされている任意の名前を割り当てることができます。ReadRows
リクエストではなく SQL を使用してビューをクエリする場合は、この方法を使用します。
SELECT
リストの集計されていない出力列は、GROUP
BY
句に含める必要があります。GROUP BY
句で列が書き込まれる順序は、継続的マテリアライズド ビューの行キーにデータが格納される順序です。たとえば、GROUP BY a, b, c
は暗黙的に ORDER BY a ASC, b ASC, c
ASC
です。
GROUP BY
句ではなく ORDER BY
句を使用して非同期セカンダリ インデックスを作成すると、ORDER BY
句の一部である SELECT
リストの列がビューの行キーになります。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
が 1 つ以上ある場合、出力行のsum_foo
は NULL 以外の値になります。 - 指定された
baz
にbar
が 1 つ以上ある場合、出力行のsum_bar
は NULL 以外の値になります。 - 指定された
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
ではなく、0 以上で、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 | NULL | 56 |
4 | 2024-05-04 00:00:00Z | 8 | NULL |
エンコード
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 | Unix エポックからのマイクロ秒数を表す 64 ビット整数(GoogleSQL と一致) |