Un query profile (Snowflake) ou un query plan / SQL profile (Databricks) sert à répondre : où part l’argent et le temps ? Pas à décorer une revue. Vous lisez de l’opérateur le plus cher vers la cause, pas de haut en bas « parce que c’est l’arbre ».
Octets scannés contre octets de la table. Si vous lisez 80 % d’une table pour un filtre censé être sélectif, le pruning a échoué : clustering, expression sur la colonne, ou micro-partitions trop « mélangées ». Agrandir le warehouse scanne autant, juste plus vite — parfois plus cher.
Spilling (local puis remote). La mémoire du t-shirt ne suffit plus ; Snowflake écrit sur disque, éventuellement distant. Là, scale-up a un sens. Sans spill et avec un scan déjà prune, passer de M à XL est du gaspillage de crédits.
Files d’attente et compilation. Du temps passé queued : problème de concurrence, pas de SQL — multi-cluster ou un warehouse dédié. Du temps cloud services / compilation sur des milliers de petites requêtes : autre ligne de facture, autre levier.
Le nœud TableScan vs Join vs Aggregate vous dit si vous payez l’I/O ou le CPU. Un join explosif (mauvais grain, filtre trop tard) se voit à la taille intermédiaire, pas au EXPLAIN théorique.
Même démarche : plus gros stage, shuffle (octets échangés), spill disque, skew (une tâche 20× plus longue). En plus : pourcentage Photon. Un SQL warehouse « Photon » à 20 % de temps Photon, c’est souvent une UDF ou un type hors couverture — vous payez le tarif sans le moteur. Scan Parquet/Delta : le read schema doit coller aux colonnes utiles ; sinon le lac se comporte en CSV déguisé.
Ne confondez pas le plan Catalyst prévu et le profil exécuté (AQE, runtime). Le coût réel est le second.
Une méthode. 1) La requête est-elle servie par un cache de résultat ? Alors vous ne mesurez rien. 2) Quel opérateur pèse 70 % ? 3) Est-ce du volume (scan), de la mémoire (spill), de la concurrence (queue) ou du modèle (join mal cadré) ? 4) Le correctif le moins cher qui s’attaque à cette cause.
La relance : « On a doublé le warehouse, c’est encore lent. » Vous refusez de redoubler. Vous ouvrez le profil : si les octets scannés n’ont pas bougé et qu’il n’y a pas de spill, le goulot n’était pas le parallélisme. Peut-être un verrou, un opérateur resté monothread, une UDF, ou un résultat trop gros renvoyé au client.
Il ne cite pas « 200 partitions » Spark par habitude, ni « toujours XL ». Il relie crédits ou DBU au profil : temps d’entrepôt allumé × taille, ou DBU × heures. Une requête de 8 secondes sur un 4XL peut coûter plus qu’une de 40 secondes sur un S. Le profil est l’endroit où on le prouve.