J'ai récemment passé la certification SnowPro Core. Et si je devais la repasser demain, cet article serait ma seule révision.

Accredible • Certificates, Badges and Blockchain
Home of digital credentials

100 questions. 115 minutes. Un score de 750 à atteindre. Et une quantité de sujets qui peut vite faire tourner la tête.

Si tu bosses avec Snowflake au quotidien ou si tu as suivi ma formation Snowflake, tu as déjà une base solide. J'ai synthétisé ici les 6 domaines de l'examen avec un seul objectif, t'apporter le maximum de valeur en un minimum de temps. Les vrais pièges, les détails et les sujets indispensables à maîtriser avant de passer la certification.

COF-C02 → COF-C03 : ce qui change

J'ai passé la version COF-C02 de l'examen. Mais il faut savoir que Snowflake a lancé une nouvelle version, la COF-C03 le 16 février 2026. La COF-C02 sera retirée le 14 mai 2026 (en anglais) et pour la version française sera retirée le 31 juillet 2026.

Concrètement, le format ne change pas (100 questions, 115 minutes, score de 750/1000 pour valider). Ce qui change, c'est le contenu. Voici les grandes lignes :

Snowflake Cortex fait son entrée dans l'examen. Il faut comprendre ce que c'est, à quoi ça sert et où ça s'inscrit dans la plateforme, mais pas besoin d'apprendre les API ou la syntaxe de toutes les fonctions Cortex.

Apache Iceberg Tables sont aussi couvertes. Il faut savoir pourquoi ces tables existent et en quoi elles diffèrent des tables natives Snowflake.

Snowflake Notebooks apparaissent aussi. Il faut connaître leur utilité et les cas d'usage.

Plus globalement, le focus de l'examen passe du data warehouse classique vers la vision AI Data Cloud de Snowflake. Le SQL reste important mais n'est plus dominant. La gouvernance est enrichie, et la partie collaboration s'étend au Marketplace et aux native apps.

La bonne nouvelle, c'est que tout ce qui est couvert dans cet article et dans ma formation reste vrai pour les deux versions sauf que la COF-C03 ajoute des sujets par-dessus, mais ne retire rien de fondamental et donc si tu passes l'examen après mai 2026, tu devras simplement compléter ta préparation avec les nouveautés Cortex, Iceberg et Notebooks.

Les 6 domaines de l'examen (COF-C02)

L'examen est découpé en 6 domaines avec un poids différent :

Domaine Poids
Architecture & AI Data Cloud 24%
Accès & Sécurité 18%
Performance & Coûts 16%
Chargement & Déchargement 12%
Transformations 18%
Protection & Partage 12%

Les deux plus gros morceaux sont l'architecture (24%) et les transformations (18%). Si tu maîtrises bien ces deux domaines, tu as déjà presque la moitié des points.

1. Architecture & AI Data Cloud (24%)

Les 3 couches de Snowflake

Si tu as lu mon article sur l'architecture Snowflake, tu connais déjà le principe. Snowflake repose sur une architecture hybride entre shared-disk et shared-nothing, organisée en trois couches : storage, compute et cloud services.

Le storage : les données sont stockées dans le cloud (S3, Azure Blob, GCS) en format compressé et colonnaire, découpé en micro-partitions. Tu ne gères pas le stockage, c'est Snowflake qui s'en occupe. Chaque micro-partition fait entre 50 et 500 MB et embarque des métadonnées (min/max par colonne, nombre de lignes, etc..) qui permettent le pruning, c'est-à-dire que Snowflake peut ignorer les partitions qui ne matchent pas ta clause where.

Le compute : ce sont les virtual warehouses. Un warehouse c'est un cluster de serveurs que Snowflake met à ta disposition pour exécuter tes requêtes. Les warehouses sont totalement indépendants les uns des autres, ce qui permet l'isolation des traitements. Un ETL qui tourne sur un warehouse ne ralentit pas les dashboards qui tournent sur un autre.

Le cloud services : c'est le cerveau de Snowflake. Il gère l'authentification, le parsing et l'optimisation des requêtes, la gestion des métadonnées, le contrôle d'accès, les transactions, le Time Travel, le data sharing, etc... C'est une couche partagée par tous les warehouses d'un même compte. Le point important à ne pas oublier c'est que le cloud services layer ne consomme des crédits que s'il dépasse 10% de la consommation totale de compute quotidienne. En dessous de ce seuil, c'est offert.

Le point clé de toute l'architecture et que le storage et le compute sont découplés. Tu peux scaler l'un sans toucher l'autre. C'est ce qui distingue Snowflake d'un data warehouse classique.

Multi-cloud

Snowflake est disponible sur les trois grands cloud providers (AWS, Azure et GCP). Tu choisis ta région au moment de la création du compte. L'intérêt c'est la flexibilité et la localité des données (tu peux stocker tes données dans la région la plus proche des utilisateurs). Snowflake fournit la même interface et les mêmes fonctionnalités quel que soit le cloud, donc tu peux changer de provider facilement.

Pour l'examen, retiens que le data sharing direct entre deux comptes Snowflake nécessite qu'ils soient dans la même région cloud. Pour le cross-region ou cross-cloud, il faut passer par un listing (Marketplace) ou la replication.

Virtual Warehouses

J'ai un article dédié ici : Virtual Warehouse Snowflake.

Les warehouses vont de X-Small à 6X-Large. Chaque taille au-dessus double le nombre de serveurs et le coût. Un X-Small consomme 1 crédit/heure, un Small 2, un Medium 4, etc.. Le choix de la taille dépend de la complexité de tes requêtes. Pour les questions de concurrence (beaucoup d'utilisateurs en parallèle), ce n'est pas la taille qu'il faut augmenter mais le nombre de clusters.

-- Scale up = augmenter la taille (requêtes plus rapides)
ALTER WAREHOUSE analytics_wh SET WAREHOUSE_SIZE = 'LARGE';

-- Scale out = multi-cluster (plus de concurrence)
ALTER WAREHOUSE analytics_wh SET
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 3;

Scale up => une requête unique s'exécute plus vite.

Scale out => plus de requêtes peuvent tourner en parallèle sans se gêner.

Nb : Le multi-cluster warehouse nécessite Enterprise Edition minimum. C'est un question très fréquente dans la certif.

Côté auto-suspend et auto-resume, le piège fréquent c'est que l'auto-suspend ne stoppe pas les requêtes en cours. Il attend que tout soit terminé, puis lance le compte à rebours. Et quand le warehouse est suspendu, il perd son cache local. Donc un auto-suspend trop court (60s) peut être une mauvaise idée si tu as des analystes qui enchaînent les requêtes toute la journée, car chaque redémarrage oblige Snowflake à tout relire depuis le storage distant et donc augmente les coûts.

-- Warehouse ETL : on suspend vite après le batch
CREATE WAREHOUSE wh_etl
  WAREHOUSE_SIZE = 'LARGE'
  AUTO_SUSPEND = 120
  AUTO_RESUME = TRUE;

-- Warehouse BI : on garde le cache chaud
CREATE WAREHOUSE wh_bi
  WAREHOUSE_SIZE = 'MEDIUM'
  AUTO_SUSPEND = 600
  AUTO_RESUME = TRUE;

Deux types de warehouses à connaître : les Standard (usage général) et les Snowpark-optimized (plus de mémoire locale, pensés pour le machine learning et les traitements Python/Java/Scala lourds dans Snowpark).

Types de tables

Article détaillé : Types de tables Snowflake.

Le choix du type de table joue sur la durée de vie de tes données et ta capacité à les restaurer (Time Travel / Fail-safe), donc sur la facture.

Les permanent tables sont le type par défaut. Elles supportent le Time Travel (jusqu'à 90 jours en Enterprise) et le Fail-safe (7 jours).

Les transient tables ont un Time Travel limité à 0 ou 1 jour et pas de Fail-safe. (spoiler j'ai eu cette question dans la certif)

C'est le bon choix pour les tables de staging ou les données intermédiaires que tu peux rejouer depuis la source.

Les temporary tables disparaissent à la fin de la session, pas de Fail-safe non plus.

Les external tables sont en lecture seule, les données vivent dans un data lake externe (S3, Azure Blob, GCS), et Snowflake ne stocke que les métadonnées.

CREATE TRANSIENT TABLE stg_events (
  event_id STRING,
  payload VARIANT,
  loaded_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP()
);

CREATE TEMPORARY TABLE tmp_calcul AS
SELECT user_id, SUM(amount) AS total
FROM orders GROUP BY user_id;

Pour l'examen : les tables transient et temporary n'ont jamais de Fail-safe, et leur Time Travel ne peut jamais dépasser 1 jour, quelle que soit l'édition Snowflake.

Stages

Article : Stages Snowflake.

3 types de stages internes à connaître :

Le user stage (@~) est personnel à chaque utilisateur, créé automatiquement.

Le table stage (@%ma_table) est lié à une table spécifique.

Le named stage (@mon_stage) est un objet créé explicitement, partageable, et c'est celui qu'on utilise dans les vrais projets.

Côté externe, un stage pointe vers un bucket cloud. La connexion se fait via une storage integration, qui est un objet Snowflake qui encapsule les credentials cloud (IAM role sur AWS, service principal sur Azure, etc..).

-- Storage integration (créée par ACCOUNTADMIN)
CREATE STORAGE INTEGRATION s3_integration
  TYPE = EXTERNAL_STAGE
  STORAGE_PROVIDER = 'S3'
  ENABLED = TRUE
  STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/snowflake-role'
  STORAGE_ALLOWED_LOCATIONS = ('s3://mon-bucket/raw/');

-- Stage externe qui utilise l'intégration
CREATE STAGE stg_s3_raw
  URL = 's3://mon-bucket/raw/'
  STORAGE_INTEGRATION = s3_integration
  FILE_FORMAT = (TYPE = PARQUET);

La storage integration est préférable aux credentials en dur dans le stage, autant pour la sécurité que pour la maintenabilité.

Directory Table

J'ai eu pas mal de questions là-dessus à l'examen. Une Directory Table c'est une couche de métadonnées automatique sur un stage qui te permet de lister et filtrer les fichiers qu'il contient, comme si c'était une table SQL.

-- Créer un stage avec Directory Table activée
CREATE STAGE stg_documents
  URL = 's3://mon-bucket/docs/'
  DIRECTORY = (ENABLE = TRUE)
  STORAGE_INTEGRATION = s3_integration;

-- Rafraîchir les métadonnées après ajout de fichiers
ALTER STAGE stg_documents REFRESH;

-- Interroger la Directory Table
SELECT relative_path, size, last_modified
FROM DIRECTORY(@stg_documents)
WHERE relative_path LIKE '%.pdf'
  AND last_modified >= DATEADD(day, -7, CURRENT_DATE());

La Directory Table expose plusieurs colonnes : RELATIVE_PATH (chemin du fichier), SIZE (taille en bytes), LAST_MODIFIED, MD5 (hash), FILE_URL et SCOPED_FILE_URL. C'est particulièrement utile pour gérer des fichiers non structurés (images, PDF, vidéos) dans un stage.

Point important c'est que après chaque ajout de fichier, il faut faire un ALTER STAGE ...... REFRESH pour mettre à jour les métadonnées. Sauf si tu as configuré un event notification cloud (comme SNS sur AWS ou Event Grid sur Azure), auquel cas le refresh se fait automatiquement.

Tu peux aussi générer des liens d'accès temporaires avec GET_PRESIGNED_URL :

SELECT relative_path,
       GET_PRESIGNED_URL(@stg_documents, relative_path, 3600) AS lien_temporaire
FROM DIRECTORY(@stg_documents);

(j'ai eu deux questions sur la génération des liens d'accès)

Time Travel, Fail-safe et Zero-Copy Clone

Articles : Time Travel & Fail-safe et Zero-Copy Clone.

Le Time Travel c'est ta capacité à remonter dans le temps sur tes données. Snowflake ne réécrit jamais les données en place, il crée de nouvelles micro-partitions et garde les anciennes versions. C'est ce qui permet de faire un SELECT dans le passé, un UNDROP ou un clone à un instant T.

-- Données telles qu'elles étaient il y a 1 heure
SELECT * FROM orders AT(OFFSET => -3600);

-- Données juste avant un statement précis
SELECT * FROM orders BEFORE(STATEMENT => '01abc234-...');

-- Restaurer une table supprimée
UNDROP TABLE orders;

-- Cloner à un instant précis via Time Travel
CREATE TABLE orders_snapshot CLONE orders
  AT(TIMESTAMP => '2025-03-01 08:00:00'::TIMESTAMP);

La rétention Time Travel par défaut est de 1 jour. Avec Enterprise Edition, tu peux aller jusqu'à 90 jours sur les tables permanentes. Le Fail-safe commence juste après la fin du Time Travel et dure 7 jours. Il n'est pas accessible en SQL, il faut passer par le support Snowflake. Donc pour restaurer tes données ou rattraper une erreur humaine, ce qui compte vraiment c'est le Time Travel.

Le zero-copy clone crée un clone qui pointe vers les mêmes micro-partitions que la source. Tant que tu ne modifies pas les données du clone, il ne consomme pas de stockage supplémentaire. C'est instantané et quasi gratuit. On peut cloner des tables, des schemas et des databases.

Nb : On ne peut pas cloner un stage externe ni une external table. Et le clone ne récupère pas l'historique Time Travel de la source, il repart de zéro.

Éditions Snowflake

Article : Éditions Snowflake.

C'est un sujet qui revient très souvent à l'examen parce que beaucoup de features sont liées à une édition minimum.

Standard : Time Travel 1 jour max, pas de multi-cluster warehouse, pas de masquage dynamique, pas de materialized views, pas de clustering.

Enterprise : Time Travel jusqu'à 90 jours, multi-cluster warehouse, masquage dynamique, row access policy, materialized views, clustering automatique, SOS, column-level security.

Business Critical : tout Enterprise + chiffrement Tri-Secret Secure (CMK client + clé Snowflake), Private Link, support HIPAA/PCI-DSS.

VPS (Virtual Private Snowflake) : tout Business Critical + isolation physique complète du compte.

Ma règle pour l'examen c'est que dès qu'une question mentionne l'optimisation, clustering, le masquage dynamique, le multi-cluster ou le Time Travel > 1 jour, la réponse implique Enterprise minimum. Dès qu'on parle de la sécurité++ comme Private Link, Tri-Secret Secure ou failover, c'est Business Critical et le VPS uniquement quand y'a la notion d'isolation physique du compte.

Snowpark, Unistore et Marketplace

Article : Snowpark Snowflake.

Snowpark permet d'écrire du code Python, Java ou Scala qui s'exécute directement dans Snowflake. Le calcul est poussé côté Snowflake (push-down), pas côté client. On manipule des DataFrames (comme dans Spark ou Pandas) et on peut créer des UDF ou des stored procedures dans ces langages. Pour les workloads lourds (ML, data science), Snowflake propose des warehouses Snowpark-optimized avec plus de mémoire locale.

Unistore introduit les hybrid tables, qui supportent à la fois le transactionnel (INSERT/UPDATE unitaires à haute fréquence avec row-level locking) et l'analytique. C'est la réponse de Snowflake pour les workloads OLTP légers, sans avoir besoin d'une base transactionnelle séparée.

Snowflake Marketplace est la plateforme pour découvrir et consommer des datasets tiers directement dans ton compte, sans copie de données. C'est basé sur le mécanisme de data sharing (listings).

2. Accès & Sécurité (18%)

Rôles et hiérarchie

Articles : Users & Accès Snowflake et Rôles système.

Dans Snowflake, les droits ne vont pas sur les users. Les droits vont sur des rôles, et ensuite les users reçoivent ces rôles. Si tu commences à donner les droits directement aux users, tu vas vite te retrouver avec un système impossible à maintenir.

Les rôles système à connaître par cœur :

ACCOUNTADMIN chapeaute tout. Il peut tout faire : resource monitors, billing, replication, etc.. À réserver aux opérations rares et à un nombre très restreint d'utilisateurs.

SECURITYADMIN gère les GRANT (qui a accès à quoi) et peut administrer tous les grants du compte.

USERADMIN crée et gère les users et les rôles.

SYSADMIN crée et gère les objets (databases, schemas, warehouses). Tous tes custom roles doivent remonter vers SYSADMIN dans la hiérarchie.

PUBLIC est le rôle par défaut attribué à tout le monde.

Et ORGADMIN existe au niveau organisation pour gérer les comptes Snowflake entre eux.

ACCOUNTADMIN
├── SECURITYADMIN
│   └── USERADMIN
├── SYSADMIN
│   └── (custom roles ici)

Le piège classique c'est que si tu crées un custom role sans le rattacher à SYSADMIN via un GRANT ROLE, le SYSADMIN ne pourra pas voir ni gérer les objets créés par ce rôle. C'est le problème des "orphan roles" et c'est une erreur fréquente.

RBAC + DAC

Article : DAC + RBAC Snowflake.

Snowflake combine deux modèles de contrôle d'accès.

Le RBAC (Role-Based Access Control) c'est le fait que les privilèges sont donnés aux rôles.

Le DAC (Discretionary Access Control) c'est le fait que le propriétaire d'un objet (le rôle qui l'a créé) contrôle qui peut y accéder.

CREATE ROLE data_analyst;

-- La chaîne complète : database → schema → objet → warehouse
GRANT USAGE ON DATABASE analytics_db TO ROLE data_analyst;
GRANT USAGE ON SCHEMA analytics_db.reporting TO ROLE data_analyst;
GRANT SELECT ON ALL TABLES IN SCHEMA analytics_db.reporting TO ROLE data_analyst;
GRANT SELECT ON FUTURE TABLES IN SCHEMA analytics_db.reporting TO ROLE data_analyst;
GRANT USAGE ON WAREHOUSE report_wh TO ROLE data_analyst;

GRANT ROLE data_analyst TO USER marie;

Si un seul privilège de la chaîne manque (USAGE sur la database, USAGE sur le schema, ou USAGE sur le warehouse), l'utilisateur est bloqué même s'il a le SELECT sur la table. C'est un piège fréquent. Et le FUTURE TABLES est indispensable pour que les droits s'appliquent aussi aux tables créées après le GRANT. (spoiler : j'ai une 5 questions sur les accès dans la certif)

Authentification

Article : MFA et Key Pair Snowflake.

Snowflake supporte plusieurs méthodes d'authentification : username/password (le basique), MFA via Duo Mobile (Snowflake recommande de l'activer pour tous les ACCOUNTADMIN), Key Pair (clé privée côté client, clé publique dans Snowflake, idéal pour les connexions automatisées comme les ETL ou Snowpipe), SSO via SAML 2.0 (fédération avec un IdP comme Okta ou Azure AD), et OAuth pour les applications tierces.

Le key pair est souvent demandé à l'examen. Le principe c'est que la clé privée ne transite jamais sur le réseau, ce qui le rend plus sécurisé que le mot de passe. Tu génères la paire avec OpenSSL, tu assignes la clé publique au user dans Snowflake, et le client utilise la clé privée pour s'authentifier.

Article : Network Policy Snowflake.

CREATE NETWORK POLICY bureau_only
  ALLOWED_IP_LIST = ('203.0.113.0/24', '198.51.100.10')
  BLOCKED_IP_LIST = ('203.0.113.50');

-- Appliquer au compte entier
ALTER ACCOUNT SET NETWORK_POLICY = bureau_only;

La BLOCKED_IP_LIST sert à exclure des IP spécifiques d'une plage déjà autorisée. Tu ne peux pas bloquer une IP qui n'est pas dans la ALLOWED_IP_LIST.

Private Link (AWS PrivateLink, Azure Private Link, GCP Private Service Connect) permet une connexion privée entre ton VPC et Snowflake sans passer par internet. mais attention cela nécessite Business Critical Edition.

Masquage dynamique et Row Access Policy

Articles : Masquage dynamique et Row Access Policy.

Le masquage dynamique agit sur les colonnes (cacher l'email, le numéro de téléphone, etc.. selon le rôle). Le Row Access Policy agit sur les lignes (un commercial ne voit que les données de sa région). Les deux nécessitent Enterprise Edition.

-- Masquage dynamique sur une colonne email
CREATE MASKING POLICY mask_email AS (val STRING)
RETURNS STRING ->
  CASE
    WHEN CURRENT_ROLE() IN ('HR_ROLE') THEN val
    ELSE CONCAT(LEFT(val, 2), '***@***')
  END;

ALTER TABLE employees MODIFY COLUMN email SET MASKING POLICY mask_email;

Pour l'examen, retiens aussi les notions de Object Tagging (attacher des tags aux colonnes pour classifier les données sensibles) et de Data Classification (Snowflake peut automatiquement détecter les colonnes PII). Ces features s'intègrent avec le masquage dynamique pour appliquer des politiques de sécurité à grande échelle.

Chiffrement

Snowflake chiffre automatiquement toutes les données au repos (AES-256) et en transit (TLS 1.2 minimum). C'est toujours activé, pas configurable. Avec Business Critical, tu as le Tri-Secret Secure qui combine une clé Snowflake et une clé client (CMK dans le KMS de ton cloud provider). Les deux clés sont nécessaires pour déchiffrer les données.

3. Performance & Coûts (16%)

Le modèle de coûts

Voir l'article : FinOps Snowflake.

Snowflake facture trois choses : le compute (crédits consommés par les warehouses, facturés à la seconde avec un minimum d'une minute), le storage (au To/mois, compressé), et les services serverless (Snowpipe, clustering automatique, materialized views, replication, etc..).

La plupart du temps, la facture explose à cause du compute mal piloté, pas à cause du storage. C'est pour ça que la séparation des warehouses par usage (ETL, BI, dev) et le paramétrage de l'auto-suspend sont si importants.

Caching

Voir l'article : Cache Snowflake.

Snowflake a trois niveaux de cache.

Le metadata cache est géré par le cloud services layer. Certaines requêtes simples (COUNT(*), MIN, MAX sans filtre complexe) peuvent être résolues uniquement à partir des métadonnées des micro-partitions, sans allumer de warehouse et donc sans coût compute.

Le result cache stocke le résultat des requêtes pendant 24 heures. Si tu relances exactement la même requête et que les données n'ont pas changé, Snowflake renvoie le résultat directement. Attention, "exactement la même" veut dire strictement identique : un alias, un espace, la casse, tout peut casser le cache.

Le warehouse cache (local disk cache) garde en mémoire locale les données lues depuis le storage. Il est perdu quand le warehouse est suspendu.

Query Profile et EXPLAIN

Article : Query Profile Snowflake.

Le Query Profile est l'outil n°1 pour diagnostiquer les problèmes de performance. Comme je le dis dans mes articles sur le clustering, le QAS et le SOS et peu importe la problématique, on commence toujours par le Query Profile ;)

Mais il y a aussi EXPLAIN, et j'ai eu pas mal de questions dessus à l'examen. EXPLAIN affiche le plan d'exécution d'une requête sans l'exécuter. C'est utile pour vérifier rapidement si le pruning fonctionne ou pour comprendre l'ordre des opérations.

-- Plan d'exécution estimé (format tabulaire par défaut)
EXPLAIN
SELECT o.order_id, c.customer_name, o.amount
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.order_date >= '2025-01-01';

-- Format JSON pour plus de détails
EXPLAIN USING JSON
SELECT * FROM orders WHERE order_date = '2025-06-15';

EXPLAIN renvoie un plan sous forme tabulaire avec des colonnes comme operation (TableScan, Filter, JoinInner, Aggregate, Sort..), objects (tables et colonnes impliquées), partitionsTotal et partitionsAssigned (c'est ici que tu vois le pruning et donc combien de micro-partitions seront lues vs le total), et bytes / rows (estimation du volume).

La différence importante entre EXPLAIN et le Query Profile c'est que EXPLAIN te donne un plan estimé avant exécution. Il ne consomme pas de crédits. Le Query Profile te montre ce qui s'est réellement passé après exécution, avec les temps réels par opérateur, les spillages disque, le pourcentage de données lues depuis le cache, etc..

Pour l'examen, retiens qu'EXPLAIN ne consomme pas de crédits (pas d'exécution), et que les estimations peuvent différer de la réalité. Le Query Profile est toujours plus fiable pour diagnostiquer un problème de performance concret.

Micro-partitions et Clustering

Articles : Clustering Snowflake.

Toutes les tables Snowflake sont découpées automatiquement en micro-partitions. Pour chaque partition, Snowflake garde des métadonnées min/max par colonne. Quand tu fais un WHERE order_date = '2025-06-15', Snowflake regarde les min/max de chaque partition et ignore celles qui ne peuvent pas contenir cette date. C'est le pruning.

Avec le clustering tu définis une clustering key pour dire à Snowflake de réorganiser les micro-partitions afin que les données similaires se retrouvent dans les mêmes partitions. C'est un service en arrière-plan (Automatic Clustering) et consomme des crédits serverless.

-- Définir une clustering key
ALTER TABLE orders CLUSTER BY (order_date);

-- Vérifier l'état du clustering
SELECT SYSTEM$CLUSTERING_INFORMATION('orders', '(order_date)');

Le clustering est utile sur les grosses tables avec des filtres récurrents. Sur une petite table, le coût de reclustering dépasse le gain. Et si le problème de ta requête n'est pas lié au nombre de partitions scannées (par exemple un join lourd ou un sort), le clustering ne changera rien. Commence toujours par le Query Profile.

Pour les clustering keys : mets en premier la colonne avec la plus faible cardinalité. La cardinalité idéale est entre 100 et 100 000 valeurs distinctes. Les UUIDs ou les colonnes avec une valeur unique par ligne sont de mauvais candidats.

QAS et SOS

Articles : QAS et SOS.

QAS (Query Acceleration Service) s'active au niveau du warehouse. Quand une requête éligible tourne, Snowflake fait appel à des ressources de calcul partagées pour paralléliser le scan. C'est fait pour les requêtes qui passent l'essentiel de leur temps à lire des données (Remote Disk I/O dominant dans le Query Profile).

SOS (Search Optimization Service) s'active au niveau de la table. Il crée des structures d'accès (search access paths) pour les recherches de valeurs exactes sur des colonnes à haute cardinalité. C'est fait pour les point lookups (WHERE id = 'xxx') où les métadonnées min/max ne suffisent pas.

En résumé : le clustering organise mieux les données, le QAS lit plus vite en parallélisant, et le SOS sait exactement où chercher.

Resource Monitors

CREATE RESOURCE MONITOR dev_monitor
  WITH CREDIT_QUOTA = 200
  FREQUENCY = MONTHLY
  START_TIMESTAMP = IMMEDIATELY
  TRIGGERS
    ON 80 PERCENT DO NOTIFY
    ON 100 PERCENT DO SUSPEND
    ON 110 PERCENT DO SUSPEND_IMMEDIATE;

ALTER WAREHOUSE dev_wh SET RESOURCE_MONITOR = dev_monitor;

Seul ACCOUNTADMIN peut créer des resource monitors. Un warehouse ne peut être assigné qu'à un seul resource monitor à la fois. SUSPEND attend la fin des requêtes en cours, SUSPEND_IMMEDIATE les coupe immédiatement. Un resource monitor au niveau account contrôle tous les warehouses du compte.

Les vues de monitoring : QUERY_HISTORY, WAREHOUSE_LOAD_HISTORY, etc..

C'est un sujet que j'ai vu revenir plusieurs fois à l'examen. Snowflake expose deux sources principales pour suivre l'usage et la consommation. Les fonctions du schéma INFORMATION_SCHEMA et les vues du schéma SNOWFLAKE.ACCOUNT_USAGE.

La différence est importante. INFORMATION_SCHEMA te donne les données des 7 à 14 derniers jours (selon la vue) sans latence.

ACCOUNT_USAGE te donne l'historique sur jusqu'à 365 jours mais avec une latence de 45 minutes à 3 heures. Pour le monitoring temps réel, tu utilises INFORMATION_SCHEMA. Pour l'analyse historique ou le FinOps, ACCOUNT_USAGE.

QUERY_HISTORY est probablement la vue la plus importante. Elle contient l'historique de toutes les requêtes exécutées sur le compte comme durée, warehouse utilisé, bytes scannés, partitions scannées, pourcentage de cache, etc....

-- Les 20 requêtes les plus lentes de la dernière semaine
SELECT query_id, query_text, warehouse_name,
       total_elapsed_time / 1000 AS duree_sec,
       bytes_scanned,
       partitions_scanned, partitions_total,
       percentage_scanned_from_cache
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE start_time >= DATEADD(day, -7, CURRENT_TIMESTAMP())
  AND execution_status = 'SUCCESS'
ORDER BY total_elapsed_time DESC
LIMIT 20;

-- Version INFORMATION_SCHEMA (temps réel, 7 derniers jours)
SELECT *
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(
  DATE_RANGE_START => DATEADD(hour, -24, CURRENT_TIMESTAMP()),
  RESULT_LIMIT => 100
));

WAREHOUSE_METERING_HISTORY donne la consommation de crédits par warehouse, par heure. C'est la base du monitoring FinOps.

-- Consommation par warehouse sur le dernier mois
SELECT warehouse_name,
       SUM(credits_used) AS total_credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
WHERE start_time >= DATEADD(month, -1, CURRENT_TIMESTAMP())
GROUP BY warehouse_name
ORDER BY total_credits DESC;

DATABASE_STORAGE_USAGE_HISTORY montre l'évolution du stockage par database (données actives + Time Travel + Fail-safe).

LOGIN_HISTORY trace toutes les tentatives de connexion au compte (réussies ou échouées, avec l'IP source, la méthode d'authentification, etc..). Utile pour l'audit de sécurité.

ACCESS_HISTORY trace qui a accédé à quelles données et quand. C'est un outil de gouvernance qui permet de savoir quel rôle a lu quelle table, quelle colonne, etc..

-- Voir qui s'est connecté au compte cette semaine
SELECT user_name, client_ip, reported_client_type, 
       first_authentication_factor, is_success
FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY
WHERE event_timestamp >= DATEADD(day, -7, CURRENT_TIMESTAMP())
ORDER BY event_timestamp DESC;

COPY_HISTORY est indispensable pour surveiller les chargements de données (COPY INTO, Snowpipe). Tu y trouves le nombre de lignes chargées, les erreurs, le statut, etc..

-- Historique des chargements de la dernière journée
SELECT * FROM TABLE(INFORMATION_SCHEMA.COPY_HISTORY(
  TABLE_NAME => 'orders',
  START_TIME => DATEADD(hour, -24, CURRENT_TIMESTAMP())
));

Pour l'examen, retiens la distinction INFORMATION_SCHEMA vs ACCOUNT_USAGE et la latence vs profondeur d'historique. L'usage de QUERY_HISTORY et WAREHOUSE_METERING_HISTORY. Et retiens que ACCOUNT_USAGE nécessite le rôle ACCOUNTADMIN (ou un rôle auquel le droit IMPORTED PRIVILEGES a été donné sur la database SNOWFLAKE).

4. Chargement & Déchargement (12%)

File Formats

Article : File formats Snowflake.

Le file format dit à Snowflake comment lire tes fichiers. Tu peux tout écrire en ligne dans le COPY, mais la bonne pratique c'est de créer un file format nommé et de le réutiliser partout.

CREATE FILE FORMAT csv_standard
  TYPE = CSV
  FIELD_DELIMITER = ','
  SKIP_HEADER = 1
  NULL_IF = ('NULL', 'null', '')
  FIELD_OPTIONALLY_ENCLOSED_BY = '"'
  COMPRESSION = AUTO;

CREATE FILE FORMAT json_events
  TYPE = JSON
  STRIP_OUTER_ARRAY = TRUE;

Formats supportés en chargement : CSV, JSON, Avro, ORC, Parquet, XML. Formats supportés en déchargement : CSV, JSON, Parquet uniquement. Avro, ORC et XML ne sont pas supportés en sortie.

La taille optimale des fichiers pour le COPY est entre 100 et 250 MB compressés.

Trop petits => overhead de gestion.

Trop gros => pas assez de parallélisme.

COPY INTO

-- Chargement depuis un stage
COPY INTO orders
FROM @stg_s3_raw/orders/
FILE_FORMAT = (FORMAT_NAME = 'csv_standard')
ON_ERROR = 'CONTINUE';

-- Chargement Parquet avec mapping par nom de colonne
COPY INTO orders
FROM @stg_s3_raw/orders/
FILE_FORMAT = (TYPE = PARQUET)
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;

Les options COPY à connaître :

ON_ERROR : CONTINUE (skip les lignes en erreur), ABORT_STATEMENT (stop tout au premier problème), SKIP_FILE (skip le fichier complet si trop d'erreurs).

Nb : la valeur par default dans Snowpipe est SKIP_FILE et dans COPY INTO ABORT_STATEMENT

VALIDATION_MODE : RETURN_ERRORS ou RETURN_ALL_ERRORS ou RETURN_n_ROWS. Ça valide les données sans les charger. Très utile pour tester avant un chargement en production.

FORCE = TRUE : par défaut, Snowflake garde en mémoire les fichiers déjà chargés (pendant 64 jours) et refuse de les recharger. FORCE contourne ce mécanisme. C'est un point important à l'examen.

MATCH_BY_COLUMN_NAME : pour Parquet et JSON, permet de matcher les colonnes par nom au lieu de par position. C'est beaucoup plus robuste si l'ordre des colonnes change dans le fichier source.

Déchargement (COPY INTO location)

COPY INTO @stg_export/rapport/
FROM (
  SELECT customer_id, SUM(amount) AS total
  FROM orders
  WHERE order_date >= '2025-01-01'
  GROUP BY customer_id
)
FILE_FORMAT = (TYPE = CSV COMPRESSION = GZIP HEADER = TRUE)
OVERWRITE = TRUE
MAX_FILE_SIZE = 268435456;  -- 256 MB

Tu peux décharger depuis une table ou depuis une requête. Les options principales sont le format de sortie, la compression, le header, la taille max par fichier et le partitionnement.

Snowpipe

Article : Snowpipe.

Snowpipe c'est le service managé de Snowflake qui surveille un stage et déclenche automatiquement un COPY quand de nouveaux fichiers arrivent. Concrètement, un pipe c'est juste un objet qui encapsule une commande COPY avec toutes ses options.

CREATE PIPE pipe_orders AUTO_INGEST = TRUE
AS
COPY INTO orders
FROM @stg_s3_raw/orders/
FILE_FORMAT = (FORMAT_NAME = 'csv_standard');

Avec AUTO_INGEST = TRUE, Snowpipe écoute les notifications cloud (SNS sur AWS, Event Grid sur Azure, Pub/Sub sur GCP) et se déclenche tout seul. Il utilise du compute serverless (pas de warehouse dédié), facturé en crédits Snowpipe à la seconde.

La différence clé avec un COPY classique c'est que COPY INTO utilise ton warehouse (tu le dimensionnes, tu le paies). Snowpipe utilise du compute géré par Snowflake, facturé à l'usage, par fichier. Si tu as des fichiers qui tombent en continu, Snowpipe est plus adapté. Pour un batch planifié une fois par jour, un COPY dans une Task reste souvent la meilleure option.

External Tables

CREATE EXTERNAL TABLE ext_logs (
  log_date DATE AS (VALUE:log_date::DATE),
  severity VARCHAR AS (VALUE:severity::VARCHAR),
  message VARCHAR AS (VALUE:message::VARCHAR)
)
WITH LOCATION = @stg_s3_raw/logs/
FILE_FORMAT = (TYPE = PARQUET)
AUTO_REFRESH = TRUE;

Les external tables sont en lecture seule. Les données restent dans le cloud storage externe. Snowflake ne stocke que les métadonnées et un mapping vers les fichiers. Pas de Time Travel, pas de Fail-safe, pas de clone possible dessus. C'est utile pour brancher Snowflake sur un data lake existant sans ingérer les données.

5. Transformations (18%)

DML

Les commandes classiques : SELECT, INSERT, UPDATE, DELETE, MERGE.

Le MERGE est très courant dans les pipelines incrémentaux. C'est un upsert qui permet de mettre à jour si l'enregistrement existe ou insérer sinon.

MERGE INTO target t
USING source s ON t.id = s.id
WHEN MATCHED AND s.updated_at > t.updated_at THEN
  UPDATE SET t.name = s.name, t.amount = s.amount, t.updated_at = s.updated_at
WHEN NOT MATCHED THEN
  INSERT (id, name, amount, updated_at)
  VALUES (s.id, s.name, s.amount, s.updated_at);

Fonctions de transformation

Article dates : Dates SQL Snowflake.

-- Dates
SELECT
  DATE_TRUNC('month', order_date) AS debut_mois,
  DATEADD('day', 30, order_date) AS date_plus_30j,
  DATEDIFF('day', created_at, shipped_at) AS delai_livraison
FROM orders;

-- Strings
SELECT
  UPPER(city) AS ville_maj,
  TRIM(customer_name) AS nom_clean,
  SPLIT_PART(email, '@', 2) AS domaine
FROM clients;

-- Conversion sécurisée
SELECT
  TRY_CAST('2025-13-01' AS DATE) AS date_invalide,   -- NULL au lieu d'erreur
  TRY_TO_NUMBER('abc') AS num_invalide                -- NULL au lieu d'erreur
FROM DUAL;

TRY_CAST et TRY_TO_NUMBER retournent NULL au lieu de planter en cas de conversion impossible. C'est souvent demandé à l'examen. Utilise-les quand tu charges des données sales.

Window Functions

Article : Window Functions Snowflake.

SELECT
  region,
  salesperson,
  revenue,
  RANK() OVER (PARTITION BY region ORDER BY revenue DESC) AS classement,
  SUM(revenue) OVER (PARTITION BY region) AS ca_total_region,
  LAG(revenue) OVER (PARTITION BY region ORDER BY revenue DESC) AS revenue_precedent
FROM sales_summary;

Vues

Article : Types de vues Snowflake.

Standard view : couche logique, pas de stockage, réévaluée à chaque requête. C'est le choix par défaut.

Secure view : la définition SQL est cachée (même via SHOW VIEWS ou GET_DDL). C'est le type recommandé pour le data sharing car tu exposes les données sans révéler ta logique métier. L'inconvénient c'est que l'optimizer Snowflake ne peut pas voir la définition pour optimiser les requêtes à travers la vue.

Materialized view : le résultat est pré-calculé et stocké physiquement. Snowflake le maintient à jour automatiquement en arrière-plan (consomme des crédits serverless). Mais attention au limitation car une seule table source possible, pas de JOIN, pas de UNION, pas de sous-requêtes dans le FROM et disponible que à partir de Enterprise Edition.

Stored Procedures et UDF/UDTF

Article : UDTF Snowflake.

Une UDF retourne une valeur (scalaire) et s'utilise dans un SELECT.

Une UDTF retourne des lignes (comme une table) et s'utilise dans le FROM.

Une stored procedure exécute de la logique procédurale (INSERT, DELETE, DDL.....) et s'appelle avec CALL.

-- UDF scalaire
CREATE FUNCTION calc_ttc(prix_ht FLOAT, taux FLOAT DEFAULT 0.20)
RETURNS FLOAT
LANGUAGE SQL
AS $$ prix_ht * (1 + taux) $$;

SELECT product_name, calc_ttc(price_ht) AS prix_ttc FROM products;

-- Stored procedure
CREATE PROCEDURE purge_old_events(retention_days INT)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
  DELETE FROM events WHERE event_date < DATEADD(day, -retention_days, CURRENT_DATE());
  RETURN 'Purge terminée';
END;
$$;

CALL purge_old_events(90);

Les UDF et stored procedures peuvent être écrites en SQL, JavaScript, Python, Java ou Scala. Pour l'examen, retiens surtout la différence d'usage entre UDF (dans un SELECT) et stored procedure (avec CALL).

Semi-structuré : VARIANT, FLATTEN

Article : Données semi-structurées Snowflake.

Le type VARIANT peut stocker du JSON, Avro, ORC ou Parquet. Tu accèdes aux champs avec la notation : et tu castes avec ::.

-- Accéder aux champs JSON
SELECT
  payload:event::STRING AS event_type,
  payload:user.name::STRING AS user_name,
  payload:user.id::INT AS user_id
FROM api_events;

-- LATERAL FLATTEN pour exploser un tableau JSON
SELECT
  e.payload:user.name::STRING AS user_name,
  item.value:product::STRING AS product,
  item.value:price::NUMBER AS price
FROM api_events e,
LATERAL FLATTEN(input => e.payload:items) item;

LATERAL FLATTEN est indispensable pour déplier les tableaux imbriqués dans du JSON. C'est un classique de l'examen. Si tu tombes sur une question avec du JSON et un tableau, la réponse est probablement FLATTEN.

Data Modeling

Snowflake ne t'impose pas de modèle, mais tu vas retrouver les concepts classiques à l'examen.

Le star schema (modèle en étoile) place une table de faits au centre avec des dimensions autour. C'est bien adapté à Snowflake grâce au stockage colonnaire et aux jointures optimisées.

Le snowflake schema (modèle en flocon) normalise davantage les dimensions (une dimension peut avoir des sous-dimensions), ce qui réduit la redondance mais ajoute des jointures.

Snowflake favorise souvent la dénormalisation pour les workloads analytiques (moins de jointures = meilleures performances en lecture). Mais rien ne t'empêche de normaliser si tu en as besoin.

Pour le semi-structuré, tu as deux approches : tout stocker dans une colonne VARIANT et requêter avec la notation :, ou aplatir le JSON à l'ingestion dans des colonnes relationnelles classiques. Le choix dépend de la stabilité du schéma source et de la fréquence des requêtes.

6. Protection & Partage (12%)

Streams et Tasks (pipelines CDC)

Articles : Streams Snowflake et Tasks Snowflake.

Un stream capture les changements (INSERT, UPDATE, DELETE) sur une table source. C'est du CDC (Change Data Capture).

Une task planifie et exécute une action SQL selon un schedule (CRON ou intervalle).

CREATE STREAM stream_orders ON TABLE orders;

CREATE TASK task_incremental
  WAREHOUSE = etl_wh
  SCHEDULE = '5 MINUTE'
WHEN SYSTEM$STREAM_HAS_DATA('stream_orders')
AS
MERGE INTO orders_reporting t
USING stream_orders s ON t.order_id = s.order_id
WHEN MATCHED AND s.METADATA$ACTION = 'INSERT' THEN
  UPDATE SET t.amount = s.amount
WHEN NOT MATCHED AND s.METADATA$ACTION = 'INSERT' THEN
  INSERT (order_id, amount, order_date)
  VALUES (s.order_id, s.amount, s.order_date);

-- Activer la task (elles sont créées en mode SUSPENDED par défaut)
ALTER TASK task_incremental RESUME;

Un stream est consommé quand une DML le lit dans une transaction. Après consommation, il se réinitialise. SYSTEM$STREAM_HAS_DATA() évite de lancer la task (et donc de réveiller le warehouse) quand il n'y a rien à traiter.

Attention à bien connaître les différents champs de la table Stream car c'est une question fréquente : METADATAROWID,METADATAROW_ID, METADATA ROWI​D,METADATAISUPDATE et METADATA$ACTION

Les tasks supportent aussi les arbres de dépendances (task parent → child tasks) pour orchestrer des pipelines en plusieurs étapes.

Dynamic Tables

Article : Dynamic Tables Snowflake.

Les Dynamic Tables arrivent avec une autre approche par rapport aux streams + tasks. Tu décris juste le résultat final (un SELECT), et Snowflake se charge de le maintenir à jour de manière incrémentale.

CREATE DYNAMIC TABLE dt_ca_quotidien
  TARGET_LAG = '30 MINUTE'
  WAREHOUSE = analytics_wh
AS
SELECT
  DATE_TRUNC('day', order_date) AS jour,
  region,
  SUM(amount) AS ca_jour,
  COUNT(*) AS nb_commandes
FROM orders
GROUP BY 1, 2;

Le TARGET_LAG définit le retard maximum acceptable. Plus c'est court, plus Snowflake rafraîchit souvent, et plus ça coûte en compute. Tu peux empiler plusieurs Dynamic Tables les unes sur les autres et Snowflake construit automatiquement le graphe de dépendances et rafraîchit dans le bon ordre.

Si ton pipeline est 100% Snowflake et surtout une suite de transformations SQL, les Dynamic Tables sont souvent l'option la plus simple. Si tu as besoin de plus de contrôle ou d'intégrations externes, streams + tasks restent plus adaptés.

Data Sharing

Article : Data Sharing Snowflake.

Le Data Sharing permet de partager des objets vers un autre compte Snowflake sans copier les données. Le provider partage, le consumer requête. Le consumer ne paie pas de storage pour les données partagées, il paie seulement le compute de ses requêtes.

-- Côté provider
CREATE SHARE share_kpis;
GRANT USAGE ON DATABASE analytics_db TO SHARE share_kpis;
GRANT USAGE ON SCHEMA analytics_db.public TO SHARE share_kpis;
GRANT SELECT ON VIEW analytics_db.public.v_shared_kpis TO SHARE share_kpis;
ALTER SHARE share_kpis ADD ACCOUNTS = orgname.consumer_account;

Le direct share est du compte à compte, dans la même région. Pour du cross-region ou cross-cloud, il faut passer par un listing (Marketplace). Le listing n'est pas un autre type de partage, c'est une façon de distribuer ton partage comme un data product avec une page descriptive, de la doc, des conditions d'accès, etc..

Snowflake recommande d'utiliser des secure views pour le data sharing, car la définition SQL est cachée du consumer.

Si le consumer n'a pas Snowflake, tu crées un reader account pour lui. Attention c'est toi qui portes la facture compute de ce reader account.

Replication et Failover

La replication permet de répliquer des databases, des schemas ou des comptes entiers vers un autre compte Snowflake (dans une autre région ou un autre cloud). C'est la base du disaster recovery.

-- Activer la réplication sur une database
ALTER DATABASE prod_db ENABLE REPLICATION TO ACCOUNTS orgname.dr_account;

-- Côté destination : créer le replica
CREATE DATABASE prod_db_replica
  AS REPLICA OF orgname.primary_account.prod_db;

-- Rafraîchir le replica
ALTER DATABASE prod_db_replica REFRESH;

Le failover permet de promouvoir le replica en primary si le compte principal est indisponible. Le failback permet de revenir à la situation initiale. Ça nécessite Business Critical Edition.

Quels sont les pièges les plus fréquents ?

Voici les points et les pièges les plus courants d'après ce que j'ai remarqué et mon expérience.

Architecture : le storage et le compute sont toujours découplés. Le cloud services layer ne coûte que s'il dépasse 10% du compute quotidien. Les micro-partitions font entre 50 et 500 MB.

Tables : les transient et temporary n'ont jamais de Fail-safe. Leur Time Travel est limité à 0 ou 1 jour max, toutes éditions confondues.

Time Travel : la rétention par défaut est 1 jour, pas 90. UNDROP fonctionne sur tables, schemas et databases. Le Fail-safe (7 jours) n'est pas accessible en SQL.

Clone : on ne peut pas cloner un stage externe ni une external table. Le clone ne récupère pas l'historique Time Travel de la source.

EXPLAIN : pas d'exécution, pas de crédits consommés, plan estimé uniquement.

DIRECTORY TABLE : nécessite un REFRESH manuel après l'ajout de fichiers (sauf event notification configurée).

COPY INTO : ne recharge pas un fichier déjà traité (historique 64 jours) sauf avec FORCE = TRUE. Fichiers optimaux entre 100 et 250 MB.

Formats : Avro et ORC en chargement uniquement, pas en déchargement.

Snowpipe : serverless, pas de warehouse dédié, facturé en crédits Snowpipe.

Cache : le result cache dure 24h et se casse à la moindre différence de syntaxe. Le warehouse cache est perdu à la suspension.

Resource monitors : ACCOUNTADMIN uniquement. Un warehouse = un seul resource monitor.

Secure views : recommandées pour le data sharing, mais potentiellement moins performantes car l'optimizer ne voit pas la définition.

VARIANT : supporte JSON, Avro, ORC, Parquet. Utilise FLATTEN pour les tableaux imbriqués.

INFORMATION_SCHEMA vs ACCOUNT_USAGE : temps réel sur 7-14 jours vs historique 365 jours avec latence. ACCOUNT_USAGE nécessite des droits sur la database SNOWFLAKE.

Data Sharing : direct share = même région et Cross-region = listing ou replication. Reader account = le provider paie le compute.

FAQ

Combien coûte la certification SnowPro Core ?

175 $ par tentative. Pas de limite sur le nombre de tentatives, mais chaque passage est facturé au plein tarif.

Combien de questions et combien de temps dure l'examen ?

100 questions (QCM, choix multiples), 115 minutes. C'est assez large si tu gères bien ton temps. Mon conseil est de faire un premier tour rapide, de flaguer les questions où tu hésites, puis d'y revenir après sans trop perdre de temps.

Quel score faut-il pour réussir ?

750 sur 1000, en scaled scoring. Ça veut dire que le score est pondéré en fonction de la difficulté des questions.

Quelle est la différence entre COF-C02 et COF-C03 ?

Le format reste identique (100 questions, 115 minutes, 750/1000). Ce qui change, c'est le contenu. La COF-C03 ajoute Snowflake Cortex, les Apache Iceberg Tables et les Snowflake Notebooks. Le focus passe du data warehouse classique vers la vision AI Data Cloud. La COF-C02 sera retirée le 14 mai 2026 en anglais et le 31 juillet 2026 en français. Tout ce qui est couvert dans cet article reste valable pour les deux versions.

Peut-on passer la SnowPro Core en français ?

Oui. La COF-C02 est disponible en français, anglais, japonais, coréen et espagnol. Si tu passes après mai 2026, tu seras sur la COF-C03. Vérifie la disponibilité des langues au moment de ton inscription, car ça peut évoluer.

Faut-il des prérequis pour passer l'examen ?

En pratique, si tu es à l'aise avec SQL et que tu as déjà manipulé Snowflake, tu pars avec une base. Si tu débutes, je te recommande de suivre d'abord ma formation Snowflake avant de te lancer dans la préparation de l'examen.

Combien de temps faut-il pour préparer la certification ?

Encore une fois, cela va dépendre vraiment de ton point de départ. Si tu travailles avec Snowflake au quotidien depuis plusieurs mois, ou si tu as suivi ma formation, tu as déjà une base très solide et quelques jours de révision ciblée peuvent suffire. Si tu pars de zéro sur Snowflake, il faut d'abord monter en compétence sur SQL et le maîtriser avant de commencer la formation ou même de préparer la certification.

La formation gratuite Snowflake suffit-elle pour réussir ?

Pour la COF-C02, ma formation Snowflake combinée à cet article couvre l'essentiel des sujets : architecture, SQL, sécurité, stages, ingestion, performance, pipelines, et les compléments orientés examen comme EXPLAIN, Directory Table ou les vues de monitoring. Par contre, si tu passes la COF-C03 (donc après mai 2026), il faudra travailler en plus les sujets qui font leur entrée dans l'examen : Snowflake Cortex, les Apache Iceberg Tables et les Snowflake Notebooks. Ces sujets ne sont pas encore couverts dans la formation, donc prévois un temps de révision supplémentaire sur la documentation officielle Snowflake pour ces trois points.

La certification SnowPro Core expire-t-elle ?

Oui, elle expire 2 ans après la date d'obtention. Pour la renouveler, tu dois passer un examen de recertification : 60 questions, 90 minutes, 88 $. C'est plus court et moins cher que l'examen initial, mais ça couvre les nouveautés de la plateforme.

Pour aller plus loin

Cet article couvre l'essentiel pour la certification SnowPro Core. Pour chaque sujet, tu trouveras un article détaillé avec des exemples concrets dans ma formation :

👉 Formation Snowflake : parcours complet

Tous les articles Snowflake sont regroupés ici :

👉 #snowflake

Tu veux qu'on discute de ton projet data (Snowflake, ingestion, modélisation, performance, coûts, gouvernance) ?

👉 Réserver un appel de 30 minutes