Utilisation de résultats de requête persistants

Lorsqu’une requête est exécutée, le résultat est conservé (c’est-à-dire mis en cache) pendant un certain temps. À la fin de la période, le résultat est purgé du système.

Snowflake utilise des résultats de requête persistants pour éviter de générer à nouveau des résultats lorsque rien n’a changé (c-à-d. optimiser la récupération). En outre, vous pouvez utiliser des résultats de requête persistants pour post-traiter les résultats (par exemple en superposant une nouvelle requête aux résultats déjà calculés).

Pour les résultats de requêtes persistantes de toutes tailles, le cache expire au bout de 24 heures.

Remarque : le jeton de sécurité utilisé pour accéder aux résultats des grandes requêtes persistantes (c’est-à-dire de taille supérieure à 100 KB) expire après 6 heures. Un nouveau jeton peut être récupéré pour accéder aux résultats pendant qu’ils sont encore en cache. Les résultats de requêtes persistantes plus petites n’utilisent pas de jetons d’accès.

Note

Le jeton fourni au connecteur Snowflake pour Spark (« connecteur Spark ») expire après 24 heures, quelle que soit la taille des résultats de la requête persistante. Le connecteur Spark tire parti du délai d’expiration plus long du cache pour éviter les expirations de délai dans certains cas d’utilisation.

Dans ce chapitre :

Optimisation de la récupération

Si un utilisateur répète une requête qui a déjà été exécutée et que les données de la ou des tables n’ont pas changé depuis la dernière fois que la requête a été exécutée, alors le résultat de la requête est le même. Au lieu d’exécuter à nouveau la requête, Snowflake peut simplement renvoyer le même résultat que précédemment. Cela peut réduire le temps de requête considérablement parce que Snowflake contourne l’exécution de la requête et, au lieu de cela, récupère le résultat directement dans le cache.

En règle générale, les résultats de la requête sont réutilisés si toutes les conditions suivantes sont remplies :

  • La nouvelle requête correspond exactement à la requête précédemment exécutée. Toute différence de syntaxe, y compris les minuscules par rapport aux majuscules, ou l’utilisation d’alias de table, empêchera 100 % de réutilisation du cache. Par exemple, considérons les requêtes suivantes, exécutées successivement :

    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;
    
    Copy

    La première requête remplira le cache et la deuxième requête identique bénéficiera de 100 % de réutilisation du cache. Cependant, les troisième et quatrième requêtes ne déclencheront pas la réutilisation du cache, simplement parce que la troisième requête introduit un alias de table et que la quatrième requête utilise des mots-clés en minuscules.

  • La requête n’inclut pas de fonctions non réutilisables, qui renvoient des résultats différents pour les exécutions successives de la même requête. UUID_STRING, RANDOM, and RANDSTR sont de bons exemples de fonctions non réutilisables.

  • La requête n’inclut pas de fonctions externes.

  • Les données de table contribuant au résultat de la requête n’ont pas changé.

  • Le résultat persistant de la requête précédente est toujours disponible.

  • Le rôle accédant aux résultats mis en cache dispose des privilèges requis.

    • Si la requête était une requête SELECT, le rôle exécutant la requête doit disposer des privilèges d’accès nécessaires pour toutes les tables utilisées dans la requête mise en cache.

    • Si la requête était une requête SHOW, le rôle exécutant la requête doit correspondre au rôle qui a généré les résultats mis en cache.

  • Toutes les options de configuration qui affectent la façon dont le résultat a été produit n’ont pas changé.

  • Les micro-partitions de la table n’ont pas changé (p. ex., elles ont été regroupées ou consolidées) en raison de modifications apportées aux autres données de la table.

Note

Le respect de toutes ces conditions ne garantit pas que Snowflake réutilise les résultats de la requête.

Par défaut, la réutilisation des résultats est activée, mais peut être remplacée au niveau du compte, de l’utilisateur et de la session à l’aide du paramètre de session USE_CACHED_RESULT.

Note

Chaque fois que le résultat persistant d’une requête est réutilisé, Snowflake réinitialise la période de conservation de 24 heures pour le résultat, jusqu’à un maximum de 31 jours à compter de la date et de l’heure de la première exécution de la requête. Après 31 jours, le résultat est purgé et la prochaine fois que la requête est soumise, un nouveau résultat est généré et persiste.

Post-traitement des résultats de requête

Dans certains cas, vous voudrez peut-être poursuivre le traitement du résultat d’une requête que vous avez déjà exécutée. Par exemple :

  • Vous développez une requête complexe étape par étape et voulez ajouter une nouvelle couche au-dessus de la requête précédente et exécuter la nouvelle requête sans recalculer les résultats partiels à partir de zéro.

  • La requête précédente était une instruction SHOW <objets>, DESCRIBE <objet> ou CALL qui renvoie des résultats sous une forme qui n’est pas facile à réutiliser.

    Par exemple, vous ne pouvez pas appeler une procédure stockée dans une instruction SQL plus complexe de la même façon que vous appelez une fonction dans une instruction SQL, donc la seule façon de traiter la sortie de la procédure stockée est de post-traiter les résultats de la requête stockée.

Le post-traitement peut être effectué à l’aide de la fonction de table RESULT_SCAN. La fonction renvoie les résultats de la requête précédente sous forme de « table », et une nouvelle requête peut alors être exécutée sur les données de la table.

Exemples

Traitez le résultat d’une commande SHOW TABLES et extrayez les colonnes et lignes suivantes du résultat :

  • schema_name, table_name et rows colonnes.

  • Les lignes de table vides.

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 |
+-----+-------------+-------------+------+
| ...                                    |
| ...                                    |
+-----+-------------+-------------+------+
Copy

D’autres exemples sont fournis dans RESULT_SCAN.