Spanner クエリ オプティマイザーは、SQL クエリを実行する最も効率的な方法を決定します。ただし、クエリ オプティマイザー自体が進化したとき、またはデータベース統計情報が更新されたときに、オプティマイザーによって決定されるクエリプランがわずかに変更される可能性があります。クエリ オプティマイザーまたは統計情報が変更されたときのパフォーマンスの低下を最小限に抑えるために、Spanner には次のクエリ オプションが用意されています。
optimizer_version: クエリ オプティマイザーの変更は、オプティマイザーのバージョンとしてバンドルされてリリースされます。Spanner は、オプティマイザの最新バージョンがリリースされてから少なくとも 30 日後に、そのバージョンをデフォルトとして使用を開始します。クエリ オプティマイザーのバージョン オプションを使用すると、古いバージョンのオプティマイザーに対してクエリを実行できます。
optimizer_statistics_package: Spanner はオプティマイザーの統計情報を定期的に更新します。新しい統計情報は、パッケージとして利用できます。このクエリ オプションは、SQL クエリのコンパイル時にクエリ オプティマイザーが使用する統計情報パッケージを指定します。指定したパッケージは、ガベージ コレクションを無効にする必要があります。
GoogleSQL
ALTER STATISTICS <package_name> SET OPTIONS (allow_gc=false)
PostgreSQL
ALTER STATISTICS spanner."<package_name>" SET OPTIONS (allow_gc = true)
このガイドでは、Spanner のさまざまなスコープでこれらの個々のオプションを設定する方法について説明します。
クエリ オプティマイザーのオプションを一覧表示する
Spanner には、利用可能なオプティマイザーのバージョンと選択可能な統計情報パッケージに関する情報が格納されています。
オプティマイザーのバージョン
クエリ オプティマイザーのバージョンは整数値であり、更新のたびに 1 単位で値が大きくなります。クエリ オプティマイザーの最新バージョンは 8 です。
次の SQL ステートメントを実行して、すべてのサポートされているオプティマイザ バージョンのリストを、それに対応するリリース日と、そのバージョンがデフォルトであるかどうかとともに返します。返される最大のバージョン番号が、サポートされている最新バージョンです。
SELECT * FROM SPANNER_SYS.SUPPORTED_OPTIMIZER_VERSIONS;
デフォルトのバージョン
デフォルトでは、Spanner は、オプティマイザの最新バージョンがリリースされてから少なくとも 30 日後に使用を開始します。新しいリリースとそのリリースがデフォルトになってからの 30 日以上の間に、新しいバージョンに対してクエリをテストして、回帰を検出することをおすすめします。
デフォルト バージョンを確認するには、次の SQL ステートメントを実行します。
SELECT * FROM SPANNER_SYS.SUPPORTED_OPTIMIZER_VERSIONS;
このクエリは、すべてのサポートされているオプティマイザー バージョンのリストを返します。IS_DEFAULT
列には、現在のデフォルトがどのバージョンかを指定します。
各バージョンの詳細については、クエリ オプティマイザーのバージョン履歴をご覧ください。
オプティマイザーの統計情報パッケージ
Spanner によって作成される新しいオプティマイザーの統計情報パッケージには、それぞれ特定のデータベース内で一意であることが保証されたパッケージ名が割り当てられます。
パッケージ名の形式は auto_{PACKAGE_TIMESTAMP}UTC
です。GoogleSQL では、ANALYZE
ステートメントが統計情報パッケージ名の作成をトリガーします。PostgreSQL では、ANALYZE
ステートメントがこのタスクを実行します。統計情報パッケージ名の形式は analyze_{PACKAGE_TIMESTAMP}UTC
です。ここで、{PACKAGE_TIMESTAMP}
は統計情報の作成開始時のタイムスタンプ(UTC タイムゾーン)です。次の SQL ステートメントを実行して、使用可能なすべてのオプティマイザーの統計情報パッケージのリストを返します。
SELECT * FROM INFORMATION_SCHEMA.SPANNER_STATISTICS;
デフォルトでは、データベースまたはクエリがこのページで説明するいずれかの方法で古いパッケージに固定されていない限り、Spanner は最新のオプティマイザー統計情報パッケージを使用します。
オプションのオーバーライド優先順位
GoogleSQL 言語データベースを使用している場合、Spanner でオプティマイザーのオプションを変更する方法はいくつかあります。たとえば、プロセスまたはクエリレベルで特定のクエリのオプションを設定することも、クライアント ライブラリのオプションを構成することもできます。オプションが複数の方法で設定されている場合、次の優先順位が適用されます。(このドキュメントのこのセクションに移動するには、リンクを選択してください)。
Spanner のデフォルト ← データベース オプション ← クライアント アプリ ← 環境変数 ← クライアント クエリ ← ステートメント ヒント
たとえば、クエリ オプティマイザーのバージョンを設定するときに優先順位を解釈する方法を次に示します。
データベースを作成する場合、Spanner のデフォルトのオプティマイザーのバージョンが使用されます。上記のいずれかの方法を使用してオプティマイザのバージョンを設定することで、オプティマイザーの左側にあるものよりも優先されます。たとえば、環境変数を使用してアプリのオプティマイザーを設定すると、データベース オプションを使用してデータベースに設定した値よりも優先されます。 ステートメント ヒントを使用してオプティマイザーのバージョンを設定すると、他の方法で設定された値よりも優先されます。
次に、各メソッドについて詳しく見ていきましょう。
データベース レベルでオプティマイザー オプションを設定する
次の ALTER DATABASE
DDL コマンドを使用して、データベースにデフォルトのオプティマイザーのバージョンを設定できます。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_version = 8);
PostgreSQL
ALTER DATABASE MyDatabase SET spanner.optimizer_version = 5;
統計パッケージは、次の例に示すように同様に設定できます。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_statistics_package = "auto_20191128_14_47_22UTC");
PostgreSQL
ALTER DATABASE MyDatabase
SET spanner.optimizer_statistics_package = "auto_20191128_14_47_22UTC";
次の DDL コマンドに示すように、複数のオプションを同時に設定することもできます。
GoogleSQL
ALTER DATABASE MyDatabase
SET OPTIONS (optimizer_version = 8,
optimizer_statistics_package = "auto_20191128_14_47_22UTC");
次のように、gcloud CLI databases ddl update
コマンドを使用して gcloud CLI で ALTER DATABASE
を実行できます。
GoogleSQL
gcloud spanner databases ddl update MyDatabase --instance=test-instance \
--ddl='ALTER DATABASE MyDatabase SET OPTIONS ( optimizer_version = 8 )'
PostgreSQL
gcloud spanner databases ddl update MyDatabase --instance=test-instance \
--ddl='ALTER DATABASE MyDatabase SET spanner.optimizer_version = 8'
データベース オプションを NULL
(GoogleSQL)または DEFAULT
(PostgreSQL)に設定することでオプションがクリアされ、デフォルト値が使用されます。
データベースの現在のオプションの値を確認するには、INFORMATION_SCHEMA.DATABASE_OPTIONS
ビューにクエリを送信するか、PostgreSQL の information_schema database_options
テーブルに対して次のクエリを実行します。
GoogleSQL
SELECT
s.OPTION_NAME,
s.OPTION_VALUE
FROM
INFORMATION_SCHEMA.DATABASE_OPTIONS s
WHERE
s.SCHEMA_NAME=""
AND s.OPTION_NAME IN ('optimizer_version', 'optimizer_statistics_package')
PostgreSQL
SELECT
s.option_name,
s.option_value
FROM
information_schema.database_options s
WHERE
s.schema_name='public'
AND s.option_name IN ('optimizer_version',
'optimizer_statistics_package')
クライアント ライブラリを使用してオプティマイザー オプションを設定する
クライアント ライブラリを介して Spanner をプログラムで操作する場合、クライアント アプリケーションのクエリ オプションを変更する方法はいくつかあります。
オプティマイザー オプションを設定するには、最新バージョンのクライアント ライブラリを使用する必要があります。
データベース クライアントのオプティマイザー オプションを設定する
アプリケーションは、次のコード スニペットに示すように、クエリ オプション プロパティを構成することで、クライアント ライブラリにオプティマイザー オプションをグローバルに設定できます。オプティマイザの設定はクライアント インスタンスに保存され、クライアントの存続期間中に実行されるすべてのクエリに適用されます。オプションはバックエンドのデータベース レベルで適用されますが、クライアント レベルで設定された場合は、そのクライアントに接続されるすべてのデータベースに適用されます。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
環境変数を使用してオプティマイザーのオプションを設定する
アプリを再コンパイルせずにさまざまなオプティマイザ バージョンを試すには、次のスニペットのように SPANNER_OPTIMIZER_VERSION
環境変数と SPANNER_OPTIMIZER_STATISTICS_PACKAGE
環境変数を設定してアプリを実行します。
Linux / macOS
export SPANNER_OPTIMIZER_VERSION="8"
export SPANNER_OPTIMIZER_STATISTICS_PACKAGE="auto_20191128_14_47_22UTC"
Windows
set SPANNER_OPTIMIZER_VERSION="8"
set SPANNER_OPTIMIZER_STATISTICS_PACKAGE="auto_20191128_14_47_22UTC"
指定されたクエリ オプティマイザー オプションの値は、クライアントの初期化時にクライアント インスタンスに読み取られて保存され、クライアントの存続期間中に実行されるすべてのクエリに適用されます。
クライアント クエリのオプティマイザーのオプションを設定する
クエリを作成するときにクエリ オプション プロパティを指定することで、クライアント アプリケーションのクエリレベルでオプティマイザーのバージョンまたは統計情報パッケージのバージョンの値を指定できます。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
ステートメント ヒントを使用してクエリのオプティマイザー オプションを設定する
ステートメント ヒントは、クエリの実行をデフォルトの動作から変更するヒントです。ステートメントに OPTIMIZER_VERSION
ヒントを設定すると、指定したクエリ オプティマイザーのバージョンを使用してそのクエリが実行されます。
OPTIMIZER_VERSION
ヒントは、オプティマイザのバージョン優先度が最も高くなります。ステートメント ヒントが指定されている場合は、他のすべてのオプティマイザーのバージョン設定に関係なく使用されます。
GoogleSQL
@{OPTIMIZER_VERSION=8} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=8*/ SELECT * FROM MyTable;
latest_version リテラルを使用して、クエリのオプティマイザのバージョンを最新バージョンに設定することもできます。
GoogleSQL
@{OPTIMIZER_VERSION=latest_version} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=latest_version*/ SELECT * FROM MyTable;
ステートメントに OPTIMIZER_STATISTICS_PACKAGE
ヒントを設定すると、指定したクエリ オプティマイザーの統計情報パッケージのバージョンを使用して、そのクエリが実行されます。指定したパッケージは、ガベージ コレクションを無効にする必要があります。
GoogleSQL
ALTER STATISTICS <package_name> SET OPTIONS (allow_gc=false)
PostgreSQL
ALTER STATISTICS spanner."package_name" SET OPTIONS (allow_gc=false)
OPTIMIZER_STATISTICS_PACKAGE
ヒントは、オプティマイザー パッケージの設定優先度が最も高くなります。ステートメント ヒントが指定されている場合は、他のすべてのオプティマイザー パッケージのバージョン設定に関係なく使用されます。
@{OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC} SELECT * FROM MyTable;
latest リテラルを使用して最新の統計情報パッケージを使用することもできます。
@{OPTIMIZER_STATISTICS_PACKAGE=latest} SELECT * FROM MyTable;
次の例に示すように、両方のヒントを 1 つのステートメントで設定できます。
default_version リテラルでは、クエリのオプティマイザのバージョンがデフォルトのバージョンに設定されます。これは、最新バージョンと異なる場合があります。詳細については、デフォルトのバージョンをご覧ください。
GoogleSQL
@{OPTIMIZER_VERSION=default_version, OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC} SELECT * FROM MyTable;
PostgreSQL
/*@OPTIMIZER_VERSION=default_version, OPTIMIZER_STATISTICS_PACKAGE=auto_20191128_14_47_22UTC*/ SELECT * FROM KeyValue;
Spanner JDBC ドライバを使用する場合にオプティマイザー オプションを設定する
次の例に示すように、JDBC 接続文字列でオプションを指定すると、オプティマイザーのバージョンと統計情報パッケージのデフォルト値をオーバーライドできます。
これらのオプションは、最新バージョンの Spanner JDBC ドライバでのみサポートされています。
次の例に示すように、SET OPTIMIZER_VERSION
ステートメントを使用してクエリ オプティマイザーのバージョンを設定することもできます。
オープンソース ドライバの使用の詳細については、オープンソース JDBC ドライバの使用をご覧ください。
無効なオプティマイザー バージョンの処理方法
Spanner では、オプティマイザーのバージョンの範囲がサポートされます。
この範囲は、クエリ オプティマイザーが更新されると変更されます。指定したバージョンが範囲外の場合、クエリは失敗します。たとえば、ステートメント ヒント @{OPTIMIZER_VERSION=9}
を使用してクエリを実行しようとしたものの、最新のオプティマイザーのバージョン番号が 8
の場合、Spanner はこのエラー メッセージで応答します。
Query optimizer version: 9 is not
supported
無効なオプティマイザー統計情報パッケージの設定を処理する
データベースまたはクエリを使用可能な統計パッケージに固定するには、このページの上記のいずれかの方法を使用します。無効な統計情報パッケージ名が指定されている場合、クエリは失敗します。クエリで指定された統計情報パッケージは、次のいずれかである必要があります。
- データベース レベルで設定されている、または
ALLOW_GC=false
とマークされている
クエリの実行に使用されるクエリ オプティマイザーのバージョンを確認する
クエリで使用されるオプティマイザーのバージョンは、Google Cloud コンソールと Google Cloud CLI に表示されます。
Google Cloud コンソール
クエリに使用されるオプティマイザーのバージョンを表示するには、Google Cloud コンソールの [Spanner Studio] ページでクエリを実行し、[説明] タブを選択します。次のようなメッセージが表示されます。
クエリ オプティマイザーのバージョン: 8
gcloud CLI
gcloud CLI でクエリを実行するときに使用されるバージョンを確認するには、次のスニペットに示すように --query-mode
フラグを PROFILE
に設定します。
gcloud spanner databases execute-sql MyDatabase --instance=test-instance \
--query-mode=PROFILE --sql='SELECT * FROM MyTable'
Metrics Explorer でクエリ オプティマイザーのバージョンを可視化する
Cloud Monitoring では、アプリケーションやシステム サービスのパフォーマンスの理解に役立つ測定値が収集されます。Spanner 用に収集される指標の 1 つは、クエリ数です。これは、一定期間にサンプリングされたインスタンス内のクエリ数を測定します。この指標は、エラーコードでグループ化されたクエリを表示するために非常に有用で、この指標を使用して各クエリの実行に使われているオプティマイザー バージョンを確認することもできます。
Google Cloud コンソールの Metrics Explorer を使用して、データベース インスタンスのクエリ数を可視化できます。図 1 は、3 つのデータベースのクエリ数を示しています。各データベースで使用されているオプティマイザーのバージョンを確認できます。
この図のグラフの下にある表は、my-db-1
での無効なオプティマイザー バージョンを使用したクエリの実行によって、Bad usage というステータスが返され、その結果、クエリ数が 0 になったことを示しています。他のデータベースでは、それぞれオプティマイザーのバージョン 1 とバージョン 2 を使用してクエリを実行しました。
図 1:Metrics Explorer に表示されるクエリ オプティマイザーのバージョン別にグループ化されたクエリの数。
インスタンスに同様のチャートを設定するには:
- Google Cloud コンソールで Metrics Explorer に移動します。
- [リソースタイプ] フィールドで
Cloud Spanner Instance
を選択します。 - [指標] フィールドで [
Count of queries
] を選択します。 - [グループ条件] フィールドで
database
、optimizer_version
、status
を選択します。
この例では、同じデータベース内の複数のクエリで異なるオプティマイザ バージョンを使用している場合は示していません。その場合は、データベースとオプティマイザのバージョンの組み合わせごとに棒グラフが表示されます。
Cloud Monitoring を使用して Spanner インスタンスをモニタリングする方法については、Cloud Monitoring を使用したモニタリングをご覧ください。