保存済みのクエリ結果の使用¶
クエリが実行されると、結果は一定期間保持(つまり、キャッシュ)されます。期間が終了すると、結果はシステムからパージされます。
Snowflakeは永続的なクエリ結果を使用して、何も変更されていない場合(「取得の最適化」)に結果が再生成されるのを防ぎます。さらに、永続的なクエリ結果を使用して結果を後処理できます(例:既に計算された結果の上に新しいクエリを重ねる)。
すべてのサイズの永続的なクエリ結果の場合、キャッシュは24時間後に期限切れになります。
大規模な 保存済みのクエリ結果(つまり、サイズが100 KB以上)にアクセスするために使用するセキュリティトークンは、6時間後に期限切れになります。結果がまだキャッシュにある間に、結果にアクセスするための新しいトークンを取得できます。より小さい保存済みのクエリ結果は、アクセストークンを使用しません。
注釈
この変更は、Spark用Snowflakeコネクタ(「Sparkコネクタ」)に提供されるトークンは、保存済みのクエリ結果のサイズに関係なく、24時間後に期限切れになります。Sparkコネクタは、より長いキャッシュ有効期限を利用して、一部のユースケースでタイムアウトを回避します。
テーブルデータがキャッシュされ、アクティブなウェアハウスで再利用される方法については、 ウェアハウスキャッシュの最適化 もご参照ください。
このトピックの内容:
取得の最適化¶
ユーザーが既に実行されたクエリを繰り返し、クエリが最後に実行されてからテーブル内のデータが変更されていない場合、クエリの結果は同じになります。Snowflakeは、クエリを再実行する代わりに、以前に返された結果と同じ結果を返します。Snowflakeはクエリの実行をバイパスし、代わりにキャッシュから直接結果を取得するため、これによりクエリ時間を大幅に短縮できます。
通常、次の条件の すべて が満たされる場合、クエリ結果が再利用されます。
新しいクエリは、以前に実行されたクエリと完全に一致する。小文字と大文字の違いや、テーブルエイリアスの使用など、構文の違いはキャッシュの100%再使用を阻害します。たとえば、次のクエリを連続して実行することを考えます。
SELECT DISTINCT(severity) FROM weather_events; SELECT DISTINCT(severity) FROM weather_events; SELECT DISTINCT(severity) FROM weather_events we; select distinct(severity) from weather_events;
最初のクエリはキャッシュに入力され、2番目のまったく同じクエリはキャッシュの100%再使用の恩恵を受けます。しかし、3番目と4番目のクエリはキャッシュ再使用をトリガーしません。3番目のクエリはテーブルエイリアスを導入し、4番目のクエリは小文字のキーワードを使用しているからです。
このクエリには、同じクエリを連続して実行した場合に異なる結果を返す、再使用できない関数は含まれていません。 UUID_STRING、 RANDOM、 RANDSTR は再使用できない関数の良い例です。
クエリには 外部関数 は含まれません。
クエリ結果に寄与するテーブルデータが変更されていない。
以前のクエリの永続化された結果が引き続き利用可能である。
キャッシュされた結果にアクセスするロールには、必要な権限がある。
クエリが SELECT クエリの場合、クエリを実行するロールには、キャッシュされたクエリで使用されるすべてのテーブルに必要なアクセス権限が必要です。
クエリが SHOW クエリの場合、クエリを実行するロールは、キャッシュされた結果を生成したロールと一致する必要があります。
結果の生成方法に影響する構成オプションが変更されていない。
テーブル内にある他のデータ変更によって、テーブルのマイクロパーティションが変更されていない(例: 再クラスタ化または統合化)。
注釈
これらの条件をすべて満たしても、Snowflakeがクエリ結果を再利用することは 保証されません。
デフォルトでは、結果の再利用が有効になっていますが、 USE_CACHED_RESULT セッションパラメーターを使用して、アカウント、ユーザー、およびセッションレベルでオーバーライドできます。
注釈
クエリの永続化された結果が再利用されるたびに、Snowflakeはクエリの最初の実行日時から最大31日まで、結果の24時間の保持期間をリセットします。31日後、結果は消去され、次回クエリが送信されると、新しい結果が生成されて保持されます。
クエリ結果の後処理¶
場合によっては、既に実行したクエリの結果に対してさらに処理を実行したい場合があります。例:
複雑なクエリを段階的に開発しており、以前のクエリの上に新しいレイヤーを追加し、部分的な結果を最初から再計算せずに新しいクエリを実行したい場合。
以前のクエリは SHOW <オブジェクト>、 DESCRIBE <オブジェクト> または CALL ステートメントで、簡単に再利用できない形式で結果が返されます。
たとえば、より複雑な SQL ステートメント内でストアドプロシージャを呼び出す方法は、 SQL ステートメント内で関数を呼び出す方法とは異なります。したがって、ストアドクエリの結果を後処理することが、ストアドプロシージャの出力を処理する唯一の方法です。
後処理は、 RESULT_SCAN テーブル関数を使用して実行できます。この関数は、以前のクエリの結果を「テーブル」として返します。その後、新しいクエリを表形式のデータで実行できます。
例¶
SHOW TABLES コマンドの結果を処理し、結果から次の列と行を抽出します。
schema_name
、table_name
、およびrows
列。空のテーブルの行。
SHOW TABLES; +-----+-------------------------------+-------------+-------+-------+------+ | Row | created_on | name | ... | ... | rows | +-----+-------------------------------+-------------+-------+-------+------+ | 1 | 2018-07-02 09:43:49.971 -0700 | employees | ... | ... | 2405 | +-----+-------------------------------+-------------+-------+-------+------+ | 2 | 2018-07-02 09:43:52.483 -0700 | dependents | ... | ... | 5280 | +-----+-------------------------------+-------------+-------+-------+------+ | 3 | 2018-07-03 11:43:52.483 -0700 | injuries | ... | ... | 0 | +-----+-------------------------------+-------------+-------+-------+------+ | 4 | 2018-07-03 11:43:52.483 -0700 | claims | ... | ... | 0 | +-----+-------------------------------+-------------+-------+-------+------+ | ... | | ... | +-----+-------------------------------+-------------+-------+-------+------+ -- Show the tables that are empty. SELECT "schema_name", "name" as "table_name", "rows" FROM table(RESULT_SCAN(LAST_QUERY_ID())) WHERE "rows" = 0; +-----+-------------+-------------+------+ | Row | schema_name | name | rows | +-----+-------------+-------------+------+ | 1 | PUBLIC | injuries | 0 | +-----+-------------+-------------+------+ | 2 | PUBLIC | claims | 0 | +-----+-------------+-------------+------+ | ... | | ... | +-----+-------------+-------------+------+
追加の例は、 RESULT_SCAN にあります。