永続的なクエリ結果の使用

クエリが実行されると、結果は一定期間(現在は24時間)保持(キャッシュ)されます。期間が終了すると、結果はシステムから削除されます。

Snowflakeは永続的なクエリ結果を使用して、何も変更されていない場合(「取得の最適化」)に結果が再生成されるのを防ぎます。

さらに、永続的なクエリ結果を使用して結果を後処理できます(例:既に計算された結果の上に新しいクエリを重ねる)。

このトピックの内容:

取得の最適化

ユーザーが既に実行されたクエリを繰り返し、クエリが最後に実行されてからテーブル内のデータが変更されていない場合、クエリの結果は同じになります。Snowflakeは、クエリを再実行する代わりに、以前に返された結果と同じ結果を返します。Snowflakeはクエリの実行をバイパスし、代わりにキャッシュから直接結果を取得するため、これによりクエリ時間を大幅に短縮できます。

通常、次の条件の すべて が満たされる場合、クエリ結果が再利用されます。

  • 新しいクエリは、以前に実行したクエリと構文的に一致する。

  • クエリ結果に寄与するテーブルデータが変更されていない。

  • 以前のクエリの永続化された結果が引き続き利用可能である。

  • キャッシュされた結果にアクセスするロールには、必要な権限がある。

    • If the query was a SELECT query, the role executing the query must have the necessary access privileges for all the tables used in the cached query.

    • クエリが SHOW クエリの場合、クエリを実行するロールは、キャッシュされた結果を生成したロールと一致する必要があります。

  • 結果の生成方法に影響する構成オプションが変更されていない。

  • クエリに、実行時に評価する必要がある関数が含まれていない(例: CURRENT_TIMESTAMP および UUID_STRING)。(CURRENT_DATE()関数はこのルールの例外です。CURRENT_DATE()は実行時に評価されますが、CURRENT_DATE()を使用するクエリはクエリ再利用機能を引き続き使用できます。)

  • テーブル内の他のデータの変更によってテーブルのマイクロパーティションが変更されていない(再クラスタ化または統合など)。

注釈

これらの条件をすべて満たしても、Snowflakeがクエリ結果を再利用することは 保証されません

デフォルトでは、結果の再利用が有効になっていますが、 USE_CACHED_RESULT セッションパラメーターを使用して、アカウント、ユーザー、およびセッションレベルでオーバーライドできます。

注釈

クエリの永続化された結果が再利用されるたびに、Snowflakeはクエリの最初の実行日時から最大31日まで、結果の24時間の保持期間をリセットします。31日後、結果は消去され、次回クエリが送信されると、新しい結果が生成されて保持されます。

クエリ結果の後処理

場合によっては、既に実行したクエリの結果に対してさらに処理を実行したい場合があります。例:

  • 複雑なクエリを段階的に開発しており、以前のクエリの上に新しいレイヤーを追加し、部分的な結果を最初から再計算せずに新しいクエリを実行したい場合。

  • 以前のクエリは SHOW <オブジェクト> または DESCRIBE <オブジェクト> ステートメントで、簡単に再利用できない形式で結果が返されます。

後処理は、 RESULT_SCAN テーブル関数を使用して実行できます。この関数は、以前のクエリの結果を「テーブル」として返します。その後、新しいクエリを表形式のデータで実行できます。

SHOW TABLES コマンドの結果を処理し、結果から次の列と行を抽出します。

  • schema_nametable_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 にあります。