G-gen の杉村です。 BigQuery の Search Index 機能が 2022年4月7日にプレビュー公開、2022年10月27日に GA されました。BigQuery に対する特定文字列の検索を高速化する当機能を解説します。
BigQuery Search Index の基本
BigQuery Search Index とは
BigQuery の Search Index とは、 BigQuery のテーブルから特定文字列を検索・抽出するようなクエリを高性能化するためのインデックス機能です。
テーブルに、カラムを指定して予めインデックスを作成しておき、SELECT 文の WHERE 句に SEARCH() 関数や =
、IN
、LIKE
などの演算子を用いることで、インデックスを利用した高速なクエリを実行できるようになります。
インデックスの更新は自動的に行われますので、一度インデックスを作成してしまえば、メンテナンスは必要ありません。
またインデックスを用いたクエリではフルスキャンが回避できますので、スキャン料金の節約にもなります。クエリによっては劇的な料金節約になる可能性があります。
なお当機能は 10GB 以上のサイズを持つテーブルにのみ有効であり、それ以下のサイズのテーブルにインデックスを作成しても、有効になりません。
ユースケース
当機能は、以下のようなユースケースが想定されます。
- ログデータの検索(システムログ、ネットワークログ、アプリのログ等)
- 法的規制などに対応するための、特定データを検索したり削除するクエリ
- セキュリティ監査
- トラブルシューティング
- 狭い範囲の特定文字列を抽出するダッシュボード作成
SEARCH() 関数を使う場合は複数カラムを横断して文字列や数値の検索が可能ですし、後述のようにネイティブ JSON 型のカラムにも対応しています。Cloud Logging で収集した Google Cloud サービスのログに対する検索などにも役立つでしょう。
BigQuery には従来、インデックスの概念がなく、インデックス設計を考慮する負担が無いことも BigQuery のメリットの一つでした。その基本姿勢を変える必要はなく、特定文字列を抽出するクエリのユースケースがある際の選択肢が増えた、と捉えればよいでしょう。
料金
インデックスを保存するための BigQuery ストレージ料金が発生します (料金ページ) 。
インデックスが使用しているストレージの量は INFORMATION_SCHEMA.SEARCH_INDEXES ビュー で確認することができます。
インデックス作成・更新処理のコンピューティング料金については、リージョンごとに規定された範囲内であれば課金されませんが、それを超える場合は Reservation を購入する必要があります。詳細は以下のドキュメントをご参照ください。
制限
対応しているカラムタイプ
以下の型のカラムに対して、インデックスを作成できます。
- STRING
- INT64
- TIMESTAMP
- ARRAY
- STRUCT
- JSON
参考 : CREATE SEARCH INDEX statement
その他の制限
その他には以下の制限があります。
- インデックスが使われるのは SEARCH() 関数もしくは WHERE 句で
=
、IN
、LIKE
など特定の演算子(operator)を使ったクエリのみ - 10 GB 以下のサイズのテーブルではインデックスが無効
- ビューやマテリアライズド・ビューにはインデックス作成不可
- ただしビューやマテリアライズド・ビューの元テーブルにインデックスが張ってあれば、ビューに対する SEARCH 関数の利用でもインデックスが利用される
- テーブルがリネームされるとインデックスが無効になる
インデックスの作成と利用
基本的な使い方
インデックスは以下のような CREATE 文で作成できます。
CREATE SEARCH INDEX my_index ON my_dataset.my_table(column_a, column_c);
作成したインデックスを利用して高速なクエリを実行するには、以下のような SELECT 文を用います。
SELECT * FROM my_dataset.my_table WHERE SEARCH(column_a, 'hogehoge');
なお、クエリ実行結果の EXECUTION DETAIL (日本語コンソールでは 実行の詳細
) を確認することで、クエリにインデックスが使われたかどうかを確認することができます。
全カラムへのインデックス作成・検索
以下のような CREATE 文で、対象テーブルの全てのカラム (対応タイプのカラムのみ) にインデックスを作成できます。
CREATE SEARCH INDEX my_index ON my_dataset.my_table(ALL COLUMNS);
また、以下のような SELECT 文でテーブル全体に対してクエリを実行できます。
SELECT * FROM my_dataset.my_table WHERE SEARCH(my_table, 'hogehoge');
インデックスが使われたかどうかの確認
クエリを実行したあと、そのクエリでインデックスが使われたかどうかを確認するには、クエリ実行後に当該ジョブのジョブ情報(Job Information)を確認します。
コンソール画面等でジョブ情報の詳細画面を表示し、インデックス使用のモード(Index Usage Mode)の項目を確認することでインデックスが使用されたかどうかがわかります。
UNUSED
: インデックスが使用されなかったPARTIALLY_USED
: クエリの一部でインデックスが使用されたFULLY_USED
: クエリの全部分でインデックスが使用された参考 : Search index usage

その他のクエリ方法
インデックスを使ったさまざまなクエリ方法や、実行結果の考え方については以下の公式ドキュメントを参照してください。
- 参考 : Search indexed data
SEARCH 関数の注意点として、例えば 192.168.10.1
のようなピリオド区切りの文字列は、パースされて 192
168
10
1
といういずれかの文字列を含む場合として検索されてしまいます。
IP アドレスを検索するときなどは `192.168.10.1`
のようにバッククォートで囲むことで、一連の文字列として認識させる必要があります。
SELECT * FROM my_dataset.my_access_log WHERE SEARCH(ip_addr, '`192.168.10.1`');
SEARCH 関数の使い方については以下をご参照ください。
- 参考 : Search functions
インデックスの削除
インデックスの削除には DROP 文を用います。
DROP SEARCH INDEX my_index ON my_dataset.my_table;
なおテーブルが削除されるとインデックスも自動的に削除されますので、削除忘れによる無駄なストレージ課金の心配はありません。
杉村 勇馬 (記事一覧)
執行役員 CTO / クラウドソリューション部 部長
元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 認定資格および Google Cloud 認定資格はすべて取得。X(旧 Twitter)では Google Cloud や Google Workspace のアップデート情報をつぶやいています。
Follow @y_sugi_it