Module d'onboarding — BigQuery
Contenu pédagogique produit par Bill (QA). Destiné à onboarding.fastodata.com.
Public : ingénieur data, SQL OK. Format : théorie d'abord → exercices → quiz corrigé.
Contexte équipe : entrepôt central, socle de dbt et de l'orchestration. Module fondamental (à faire avant dbt).
Durée estimée : ~3-4 h.
Objectifs pédagogiques
À la fin, l'apprenant sait :
- Expliquer l'architecture serverless de BigQuery (stockage/calcul séparés, slots).
- Organiser project → dataset → table ; types de tables (native, externe, vue, vue matérialisée).
- Maîtriser le coût : partitionnement, clustering,
--dry-run, éviterSELECT *. - Écrire des requêtes performantes et lire le query plan.
- Charger/exporter la donnée (batch, streaming, fédéré).
- Gérer accès et bonnes pratiques FinOps.
Module 1 — Modèle mental & architecture
BigQuery est un entrepôt serverless : pas de cluster à gérer. Deux ressources découplées :
- Stockage en colonnes (Capacitor), facturé au Go stocké.
- Calcul en slots (unités de parallélisme), facturé soit à la donnée scannée (on-demand), soit en capacité réservée (slots).
Hiérarchie : Project → Dataset → Table/View. Le dataset porte la localisation (région, ex. EU) et les ACL.
⚠️ Le levier de coût n°1 = la quantité de données scannées par requête (mode on-demand). Réduire les colonnes et les partitions lues = payer moins.
Module 2 — Tables, partitions, clustering
Types de tables :
- native : stockée dans BigQuery.
- externe : pointe des fichiers (GCS, Sheets…) — pas de stockage BQ, perfs moindres.
- vue : requête sauvegardée, recalculée à chaque appel.
- vue matérialisée : résultat pré-calculé et rafraîchi auto (cache intelligent).
Partitionnement (découpe physique d'une table) :
CREATE TABLE ventes.orders (order_id INT64, order_date DATE, amount NUMERIC)
PARTITION BY order_date;
Une requête filtrée sur order_date ne scanne que les partitions utiles (= partition pruning) → coût ↓↓. Partitions courantes : par date/timestamp, par ingestion _PARTITIONTIME, ou par range d'entier.
Clustering (tri physique dans la partition, jusqu'à 4 colonnes) :
CREATE TABLE ventes.orders (...) PARTITION BY order_date CLUSTER BY customer_id;
Accélère filtres/agrégations sur les colonnes de cluster. Partition + cluster = combo standard sur les grosses tables.
Module 3 — Maîtriser le coût (FinOps) — LE module clé
SELECT *est l'ennemi : BigQuery est colonnaire → scanner toutes les colonnes coûte cher. Ne sélectionne que les colonnes utiles.- Estimer AVANT d'exécuter :
bq query --dry-runou le badge « This query will process X » dans l'UI. Réflexe systématique. - Filtrer sur la colonne de partition pour déclencher le pruning.
- Aperçu gratuit :
tbl.preview/LIMITne réduit PAS la donnée scannée (LIMIT s'applique après le scan). Pour échantillonner sans coût :TABLESAMPLEou la preview UI. - Cache : un résultat identique re-servi du cache = gratuit.
- Maximum bytes billed : garde-fou par requête pour éviter une facture surprise.
Le bon réflexe d'équipe :
--dry-run→ regarder les Go scannés → optimiser (colonnes + partition) → exécuter.
Module 4 — Requêtes performantes
- Approx quand l'exact n'est pas requis :
APPROX_COUNT_DISTINCT()>>COUNT(DISTINCT)sur gros volumes. - Window functions,
QUALIFYpour filtrer sur une window sans sous-requête :
SELECT * FROM orders
QUALIFY ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) = 1;
- Évite les jointures explosives ; filtre tôt ; pré-agrège.
- STRUCT / ARRAY (données imbriquées) : BigQuery est fait pour le semi-structuré ;
UNNEST()pour aplatir. - Lire le query plan (onglet Execution details) : repérer les étapes qui scannent/brassent le plus.
Module 5 — Charger & exporter
- Batch load : depuis GCS (CSV/JSON/Avro/Parquet/ORC) via
bq loadou l'API. Parquet/Avro = schéma porté, recommandé. - Streaming :
tabledata.insertAll/ Storage Write API pour de l'insert temps réel. - Requêtes fédérées : interroger GCS, Cloud SQL, Sheets sans importer.
- Export : vers GCS (
EXPORT DATA OPTIONS(...)). - Scheduled queries : planifier une requête récurrente (petite orchestration native).
Module 6 — Accès, sécurité, bonnes pratiques
- IAM au niveau project/dataset ; rôles (
dataViewer,dataEditor,jobUser…). - Vues autorisées / row/column-level security pour exposer un sous-ensemble.
- Labels sur jobs/datasets pour le suivi de coût.
- Bonnes pratiques : datasets par domaine + environnement (
raw,staging,mart× dev/prod) — cohérent avec les couches dbt ; conventions de nommage ; expiration des tables temporaires.
Exercices
- Crée une table
orderspartitionnée parorder_date, clusterée parcustomer_id. Pourquoi ce combo ? - Tu dois sommer
amountsur janvier 2024. Écris la requête qui scanne le MOINS de données possible. Quel filtre déclenche le pruning ? - Avant de lancer une requête sur une table de 4 To, comment estimes-tu le coût ? Quelle commande ?
- Récupère la dernière commande de chaque client en une requête, sans sous-requête imbriquée. Quel mot-clé ?
- Pourquoi
SELECT *est-il coûteux ici alors qu'il serait neutre sur une base ligne (Postgres) ?
Quiz final corrigé
Q1. Qu'est-ce qui est facturé en mode on-demand ?
→ La donnée scannée par la requête (pas le nombre de lignes retournées). D'où l'importance des colonnes/partitions lues.
Q2. À quoi sert le partitionnement, concrètement sur le coût ?
→ Filtrer sur la colonne de partition ne scanne que les partitions utiles (pruning) → moins de données scannées → moins cher.
Q3. LIMIT 10 réduit-il le coût d'une requête ?
→ Non : le LIMIT s'applique après le scan. Pour limiter le coût : sélectionner moins de colonnes, filtrer sur partition, ou TABLESAMPLE.
Q4. Partitionnement vs clustering ?
→ Partition = découpe physique par valeur (souvent date) → pruning. Clustering = tri physique dans la partition (jusqu'à 4 cols) → filtres/agrégations plus rapides. On combine les deux.
Q5. Comment estimer le coût d'une requête sans l'exécuter ?
→ bq query --dry-run (ou l'estimation « will process X bytes » de l'UI).
Q6. Pourquoi SELECT * coûte cher sur BigQuery ?
→ Stockage colonnaire : * force le scan de toutes les colonnes ; ne lire que les colonnes nécessaires réduit fortement la donnée scannée.
Q7. native vs externe vs vue matérialisée ?
→ native = stockée dans BQ (perf max). externe = pointe des fichiers (pas de stockage BQ, perf moindre). vue matérialisée = résultat pré-calculé rafraîchi auto (cache).
Pour aller plus loin
- Doc BigQuery (pricing, partitioning, BI Engine, BQML).
- Skills équipe :
bigquery,bigquery-finops,bigquery-ml,bigquery-schema-validation. - Lien avec dbt : BQ est la cible d'exécution des modèles ; les conventions de datasets (raw/staging/mart) reflètent les couches dbt.