Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

📈 BigQuery – Data Warehouse Serverless (SQL, Dremel & Slots)

Guide complet IDEO-Lab sur le Data Warehouse (DWH) de Google Cloud (GCP).

1.1

Concept : DWH Serverless

Data Warehouse (EntrepÎt) managé (SaaS), SQL, "Serverless".

BigQuery Data Warehouse Serverless
1.2

Architecture (Google)

Colossus (Stockage), Dremel (Compute), Jupiter (Réseau).

Dremel Colossus Jupiter
1.3

vs. Redshift / Snowflake

Comparaison (Serverless vs Provisionné).

Snowflake Redshift
2.1

Hiérarchie (Projet/Dataset)

Projet (Conteneur) -> Dataset (Base) -> Table (Données).

Project Dataset Table
2.2

Schéma (Schema)

Types (STRING, INT64), Mode (NULLABLE, REQUIRED).

Schema
2.3

Types : Nested (JSON)

STRUCT (Objet) et ARRAY (Répété). Dénormalisation.

STRUCT ARRAY UNNEST
3.1

Séparation Stockage/Compute

Stockage (Colossus) vs Calcul (Dremel). (Similaire Snowflake).

Stockage Compute
3.2

Stockage : Colonnaire

Stockage (Capacitor). Optimisé pour SELECT (scan colonnes).

Colonnaire Capacitor
3.3

Stockage : Time Travel

FOR SYSTEM_TIME AS OF ... (Snapshot, 7 jours défaut).

Time Travel Snapshot
4.1

Compute : Slots

Unité de calcul (CPU/RAM/Réseau) de Dremel.

Slots Dremel
4.2

Compute : On-Demand (Défaut)

Facturation "au To scanné" (Pay-per-query). (Pool partagé).

On-Demand Pay-per-query
4.3

Compute : Reservations (Slots)

Facturation "au temps" (Flat-Rate, Flex). (Slots dédiés).

Reservations Flat-Rate
5.1

Ingestion : Batch (bq load)

Chargement (Gratuit) depuis GCS (Parquet, Avro, CSV).

Batch Load GCS Parquet
5.2

Ingestion : Streaming (API)

tabledata.insertAll (Coûteux). Temps réel.

Streaming API
5.3

Ingestion : Tables Externes

"FĂ©dĂ©rĂ©". RequĂȘte (lente) sur GCS/Drive sans ingestion.

External Table Fédéré
6.1

RequĂȘtes : Standard SQL

Dialecte (Google Standard SQL) vs Legacy SQL.

SQL Standard SQL
6.2

RequĂȘtes : UNNEST()

La fonction "JOIN" pour les ARRAY (Types Nested).

UNNEST ARRAY
6.3

RequĂȘtes : UDFs

User-Defined Functions (SQL ou JavaScript).

UDF JavaScript
7.1

Optimisation : Partitioning

Partitionnement (Temps (_PARTITIONTIME) ou Entier).

Partitioning _PARTITIONTIME
7.2

Optimisation : Clustering

Tri (CLUSTER BY). (Similaire Z-Order/Snowflake).

Clustering
7.3

Outils : BQML & BI Engine

BigQuery ML (SQL) & BI Engine (Cache In-Memory).

BQML BI Engine
1.1 Concept : Data Warehouse (DWH) Serverless
Qu'est-ce que BigQuery ?

BigQuery (BQ) est un Data Warehouse (EntrepÎt de Données) entiÚrement managé (SaaS) et "Serverless" (sans serveur), fourni par Google Cloud (GCP).

Il est conçu pour l'analytique (BI) à trÚs grande échelle (Pétaoctets) en utilisant une interface SQL.

Philosophie "Serverless"

Contrairement à Redshift (legacy) ou Snowflake (Virtual Warehouses), BigQuery est (par défaut) purement Serverless.

  • Il n'y a aucun cluster (VMs) Ă  dĂ©marrer, configurer, ou Ă©teindre.
  • Il n'y a pas de "cold start" (dĂ©marrage Ă  froid).
  • Vous envoyez une requĂȘte SQL, et BQ (Dremel) provisionne automatiquement des milliers de "Slots" (unitĂ©s de calcul) pour l'exĂ©cuter, puis les libĂšre.
Tarification (Défaut)

Le modÚle par défaut (On-Demand) est basé sur deux axes (séparés) :

  • 1. CoĂ»t de Stockage (Storage) : (TrĂšs faible) $ par Go/mois (stockĂ© dans Colossus).
  • 2. CoĂ»t de Calcul (Compute) : (ÉlevĂ©) $ par TĂ©raoctet (To) scannĂ© (lu) par vos requĂȘtes SELECT.

(PiĂšge) Une requĂȘte SELECT * FROM ma_table_10To scannera 10To, mĂȘme si vous ajoutez LIMIT 10. L'optimisation (Partitioning, Clustering) est vitale pour contrĂŽler les coĂ»ts.

1.2 Architecture (Dremel, Colossus, Jupiter)

BigQuery (SaaS) sépare totalement le stockage (Colossus) et le calcul (Dremel), reliés par le réseau (Jupiter).

(RequĂȘte SQL)
     │
     ▌
[ 1. Dremel (Compute Engine) ]
   (Le "Cerveau" / Moteur de RequĂȘte)
   (Lit le SQL, crée l'arbre d'exécution)
   (Dispatch les tĂąches aux "Slots" (Workers))
       │
       │ (Lit les donnĂ©es via le rĂ©seau)
       ▌
[ 2. Jupiter Network (Réseau Google) ]
   (Réseau "Petabit/s" interne de Google)
   (Permet le "Shuffle" massif)
       │
       │ (Lit les blocs de donnĂ©es)
       ▌
[ 3. Colossus (Storage) ]
   (Le "Disque Dur" / Stockage)
   (Successeur de GFS. Stockage Colonnaire 'Capacitor')
  • Colossus : Le systĂšme de fichiers (stockage) distribuĂ© global de Google. (Stocke les tables BQ, rĂ©pliquĂ©es).
  • Dremel : Le moteur de requĂȘte (Compute). C'est le "cerveau" qui exĂ©cute le SQL (via des "Slots") en parallĂšle (MPP).
  • Jupiter : Le rĂ©seau (SDN) interne de Google (trĂšs rapide) qui connecte Dremel (Compute) Ă  Colossus (Stockage) pour le "Shuffle" (ex: GROUP BY).
1.3 Comparaison : BigQuery vs. Redshift vs. Snowflake
CritĂšreBigQuery (Google)SnowflakeAmazon Redshift
ArchitectureFull Serverless (SaaS).SaaS (Séparation Stockage/Compute).(Legacy) Cluster Provisionné (Couplé).
(Moderne) RA3 (Séparé).
ModÚle ComputeOn-Demand (Slots partagés) ou Reservations (Slots dédiés).Virtual Warehouses (Clusters dédiés, isolés).Cluster Provisionné (dc2.large, ra3.xlplus).
Tarification (Compute)$/To Scanné (On-Demand) ou $/Slot-heure (Reservations).$/Seconde (Warehouse RUNNING).$/Heure (Cluster ON, 24/7).
Scaling (Compute)Instantané (Auto) (On-Demand).Rapide (1-3 sec) (Resize Warehouse).Lent (Minutes/Heures) (Resize Cluster).
Admin (DBA)Zéro Admin (Pas d'INDEX, VACUUM).Zéro Admin (Pas d'INDEX, VACUUM).Admin Lourd (VACUUM, ANALYZE, SORT KEY).
ÉcosystùmeGCP (Natif).Multi-Cloud (AWS, Azure, GCP).AWS (Natif).
2.1 Hiérarchie (Project / Dataset / Table)

L'adressage (namespace) dans BigQuery (non-UC) suit une hiérarchie à 3 niveaux.

-- Syntaxe (Standard SQL) :
SELECT * FROM `[PROJET].[DATASET].[TABLE]`
NiveauDescriptionÉquivalent SQL
Projet (Project)(Niveau GCP) L'unité de facturation et de permissions (IAM).(Serveur/Instance)
Dataset (Jeu de Données)Un "dossier" ou "schéma" qui regroupe des tables. (Niveau de la localisation : EU, US).Database (Base de Données)
TableL'objet (lignes/colonnes) contenant les données.Table
-- Exemple de requĂȘte
SELECT
  SUM(total_amount)
FROM
  `ideo-project-prod.sales_eu.invoices_2025`
WHERE
  country = 'FR'
2.2 Schéma (Schema)

BigQuery est un DWH "Schema-on-Write". Le Schéma (la structure) de la table est défini (strict) lors de la création de la table.

Types (Extraits)
TypeDescription
STRINGTexte (UTF-8)
INT64 / INTEGEREntier 64 bits
FLOAT64 / NUMERIC / BIGNUMERICDécimaux (Précision variable)
BOOLTRUE / FALSE
TIMESTAMPHorodatage (UTC)
DATE / DATETIMEDate / Date+Heure (local)
STRUCT (ou RECORD)(Type Complexe) Objet (JSON) (voir 2.3)
ARRAY(Type Complexe) Liste (Répété) (voir 2.3)
Mode (Contrainte)
  • NULLABLE (DĂ©faut) : La colonne peut contenir NULL.
  • REQUIRED : La colonne ne peut pas contenir NULL. (NOT NULL).
2.3 Types : Nested (STRUCT & ARRAY)

La force de BigQuery (comparé aux DWH SQL traditionnels) est sa capacité à gérer nativement des données dénormalisées (JSON/Protobuf) via les types STRUCT et ARRAY.

STRUCT (Objet)

Un STRUCT est un "conteneur" (un objet) qui regroupe des champs.

ARRAY (Répété)

Un ARRAY est une liste (un champ "répété").

Exemple (Schéma Dénormalisé)

Au lieu de 3 tables (commandes, lignes_commande, client), on peut tout stocker dans 1 table (commandes) :

Table: 'commandes'
[
  {
    "commande_id": "1001",
    "date": "2025-01-15",
    
    "client": { (STRUCT)
      "nom": "Alice",
      "email": "alice@mail.com"
    },
    
    "lignes": [ (ARRAY de STRUCTs)
      { "produit_id": "A10", "quantite": 2, "prix": 10.00 },
      { "produit_id": "B20", "quantite": 1, "prix": 50.00 }
    ]
  },
  ...
]

Avantage : Évite les JOIN coĂ»teux (les donnĂ©es sont prĂ©-jointes).
InconvĂ©nient : NĂ©cessite UNNEST (6.2) pour requĂȘter.

3.1 Architecture (Séparation Stockage/Compute)

L'architecture de BigQuery (comme Snowflake) sépare totalement le Stockage (Données) et le Calcul (Compute).

[ COUCHE 1 : STOCKAGE (Colossus) ]
  (Facturé au Go/mois)
  (Stocke les tables (format Capacitor))
  
  (Séparation physique/réseau)
  
[ COUCHE 2 : COMPUTE (Dremel) ]
  (Facturé au To scanné (On-Demand)
   OU au Slot/heure (Reservations))
Avantages (Similaire Ă  Snowflake 1.2)
  • ScalabilitĂ© IndĂ©pendante : Vous pouvez stocker 10 PĂ©taoctets (Stockage) sans payer pour le Calcul (Compute), ou lancer une requĂȘte massive (Compute) sur 10 Ko (Stockage).
  • Isolation : (Contrairement Ă  Snowflake) Le modĂšle "On-Demand" (4.2) est "multi-tenant" (partagĂ©). Pour une isolation (Workload) totale, il faut utiliser des Reservations (4.3).
3.2 Stockage : Colonnaire (Capacitor)

BigQuery (comme tous les DWH analytiques) utilise un stockage colonnaire.

Capacitor : C'est le format de stockage (successeur de Parquet/Dremel) utilisé par BigQuery (sur Colossus).

Ligne (OLTP) vs Colonne (OLAP)
Stockage "Ligne" (Row-based) (MySQL, Postgres)

Optimisé pour INSERT/UPDATE.

(Ligne 1) [ID_A | Nom_A | Ville_A]
(Ligne 2) [ID_B | Nom_B | Ville_B]
(Ligne 3) [ID_C | Nom_C | Ville_C]

ProblĂšme (RequĂȘte) : SELECT AVG(Age) doit lire tout le bloc (ID, Nom, Ville, Age) pour chaque ligne (lent).

Stockage "Colonne" (Columnar) (BigQuery, Snowflake)

Optimisé pour SELECT (OLAP).

(Fichier Col_ID)   [ID_A | ID_B | ID_C]
(Fichier Col_Nom)  [Nom_A | Nom_B | Nom_C]
(Fichier Col_Ville) [Ville_A | Ville_B | Ville_C]
(Fichier Col_Age)  [Age_A | Age_B | Age_C]

Solution : SELECT AVG(Age) ne lit que le fichier "Col_Age" (trĂšs rapide) et ignore les autres (Nom, Ville...).

C'est pour cela que la tarification BQ est au "To scanné" et que SELECT * (qui scanne toutes les colonnes) est trÚs cher.

3.3 Stockage : Time Travel

Le Time Travel (Voyage Temporel) (similaire Ă  Snowflake) permet de requĂȘter l'Ă©tat d'une table tel qu'il Ă©tait dans le passĂ©.

Fonctionnement : BigQuery (stockage immuable) conserve un historique (jusqu'à 7 jours par défaut) des données (avant UPDATE/DELETE).

Syntaxe (FOR SYSTEM_TIME AS OF)
-- (Scénario : Un 'DELETE FROM users' a été lancé
--  par erreur Ă  14:00:00)

-- 1. Restaurer la table (complĂšte)
-- (Créer une copie 'backup' de la table
--  telle qu'elle était à 13:59:00)
CREATE TABLE users_backup AS
SELECT *
FROM users
FOR SYSTEM_TIME AS OF '2025-11-10 13:59:00'

-- 2. RequĂȘter les donnĂ©es (il y a 1h)
SELECT *
FROM users
FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
Snapshots (Copies)

Si 7 jours ne suffisent pas, vous pouvez créer un SNAPSHOT (instantané) (zéro-copie, métadonnées) d'une table pour la conserver (coût de stockage).

4.1 Compute : Slots (Dremel)

Un Slot (Emplacement) est l'unité de calcul (Compute) de BigQuery (Dremel).

C'est une unitĂ© virtuelle (abstraite) de CPU, RAM, et RĂ©seau (IO) nĂ©cessaire pour exĂ©cuter une "Ă©tape" (stage) d'une requĂȘte SQL.

Fonctionnement (Exécution ParallÚle)
(RequĂȘte: "SELECT AVG(col) FROM table GROUP BY ...")
   │
   ▌
[ Dremel (Optimizer) ]
   │ (DĂ©coupe en "stages")
   │
   ├─â–ș [ Stage 1 (Read) ] -> (Slot 1, Slot 2, ...)
   ├─â–ș [ Stage 2 (Shuffle)] -> (Slot 500, Slot 501, ...)
   └─â–ș [ Stage 3 (Agg)  ] -> (Slot 1000)

BigQuery (Dremel) parallĂ©lise massivement la requĂȘte en la distribuant Ă  des milliers de Slots.

4.2 Compute : ModÚle "On-Demand" (Défaut)

C'est le modÚle de facturation (Compute) par défaut de BigQuery.

Fonctionnement (Pool Partagé)

Vous ne payez pas pour les "Slots" (4.1). Vous payez par Téraoctet (To) scanné (lu) (ex: ~$6.00 / To).

Votre requĂȘte est exĂ©cutĂ©e sur un pool "partagĂ© (shared)" massif de Slots (ex: 2000-3000 Slots) gĂ©rĂ© par Google (Fair Use).

  • Avantage : Simple (pay-as-you-go), rapide (accĂšs Ă  un pool immense pour les requĂȘtes "spiky").
  • InconvĂ©nient : CoĂ»t imprĂ©visible (une mauvaise requĂȘte SELECT * peut coĂ»ter 100$).
  • InconvĂ©nient : Performance non garantie ("Fair Use" - si les voisins sont bruyants, vos 2000 slots peuvent ĂȘtre lents).
4.3 Compute : ModĂšle "Reservations" (Flat-Rate/Flex)

C'est le modÚle de facturation (Compute) alternatif. Vous ne payez plus au "To scanné". Vous achetez (réservez) une capacité de Slots (dédiés), facturée au temps (heure/seconde).

Types de Réservations
  • Flat-Rate (Fixe) : (Engagement) Vous achetez N Slots (ex: 500) pour une longue durĂ©e (ex: 1 an). (CoĂ»t prĂ©visible, le moins cher).
  • Flex Slots : (Élastique) Vous achetez N Slots (ex: 1000) pour une courte durĂ©e (ex: 60 secondes minimum). (IdĂ©al pour les pics ETL de nuit).
  • Avantage : CoĂ»t prĂ©visible (le prix est fixe, que vous scanniez 1 To ou 1 PĂ©taoctet).
  • Avantage : Performance garantie (vous avez vos 500 Slots dĂ©diĂ©s, pas de "voisins").
  • InconvĂ©nient : CoĂ»teux si inutilisĂ©.
5.1 Ingestion : Batch (bq load)

L'ingestion "Batch" (par lots) est la méthode standard (et la moins chÚre) pour charger des données.

Coût (Gratuit)

Le chargement (Load) de données (depuis GCS ou local) dans BigQuery est GRATUIT. (Contrairement à l'ingestion "Streaming" (5.2)).

Formats Recommandés

BigQuery peut charger du CSV, JSON... mais les formats colonnaires (auto-descriptifs) sont fortement recommandés :

  • Parquet (Standard Spark/Hadoop)
  • Avro (GĂšre l'Ă©volution de schĂ©ma)
Exemple (CLI bq)
# Charger un fichier Parquet (depuis GCS)
# (Auto-détecte le schéma)
bq load --source_format=PARQUET \
    mon_dataset.ma_table \
    gs://mon-bucket/data/fichier.parquet
    
# Charger un CSV (en spécifiant le schéma)
bq load --source_format=CSV --skip_leading_rows=1 \
    mon_dataset.ma_table \
    gs://mon-bucket/data/fichier.csv \
    nom:STRING,age:INT64
5.2 Ingestion : Streaming (API)

L'ingestion "Streaming" est la méthode temps réel. Elle est utilisée pour insérer des données (ligne par ligne) immédiatement (ex: logs d'application, événements IoT).

API (tabledata.insertAll)

Le streaming se fait via un appel API (HTTP POST) (généralement via les SDKs GCP).

Coût : Le streaming est PAYANT (facturé au $/Go inséré).

// (Exemple (pseudo-code) Python SDK)
client = bigquery.Client()
table_ref = client.dataset("mon_dataset").table("ma_table")

rows_to_insert = [
    {"nom": "Alice", "age": 30},
    {"nom": "Bob", "age": 31},
]

# (Appel API HTTP)
errors = client.insert_rows_json(table_ref, rows_to_insert)

if errors == []:
    print("OK")
5.3 Ingestion : Tables Externes (Fédérées)

Une Table Externe (FĂ©dĂ©rĂ©e) est une "vue" (Read-Only) qui permet Ă  BigQuery de requĂȘter des donnĂ©es qui se trouvent Ă  l'extĂ©rieur de BigQuery (ex: dans GCS, Google Drive), sans les ingĂ©rer.

-- (Création d'une table externe pointant vers GCS)
CREATE EXTERNAL TABLE mon_dataset.logs_externes
OPTIONS (
  format = 'CSV',
  uris = ['gs://mon-bucket/logs/*.csv']
);

-- (RequĂȘte)
SELECT * FROM mon_dataset.logs_externes LIMIT 10;
  • Avantage : Permet de "tester" (explorer) des donnĂ©es (Data Lake) sans payer le coĂ»t de stockage BQ.
  • InconvĂ©nient : Performance trĂšs faible (BigQuery doit lire les fichiers GCS Ă  chaque requĂȘte, sans l'optimisation "Capacitor").
6.1 RequĂȘtes : Standard SQL

BigQuery supporte deux dialectes SQL :

  • Legacy SQL (SQL Historique) : (ObsolĂšte) L'ancien dialecte (syntaxe [projet:dataset.table]). À ne plus utiliser.
  • Standard SQL (Google SQL) : (DĂ©faut) Le dialecte moderne, conforme Ă  la norme SQL 2011.

(Pour activer : #standardSQL en haut de la requĂȘte, ou (dĂ©faut) dĂ©cocher "Use Legacy SQL" dans l'UI).

Syntaxe (Standard SQL)
# (Utilise les backticks ` ` (pas ' ou "))
SELECT
    t1.colonneA,
    SUM(t1.colonneB) AS total
FROM
    `mon-projet.mon_dataset.ma_table` AS t1
JOIN
    `mon-projet.mon_dataset.autre_table` AS t2
    ON t1.id = t2.id
WHERE
    t1.date > '2025-01-01'
GROUP BY
    1  -- (Group by 'colonneA')
ORDER BY
    total DESC
LIMIT 100
CTE (Common Table Expressions) - WITH

L'utilisation de WITH (CTEs) est la meilleure pratique pour organiser des requĂȘtes complexes.

WITH
  etape_1 AS (
    SELECT ... FROM `table_a`
  ),
  etape_2 AS (
    SELECT ... FROM `table_b`
  )
SELECT
  e1.col, e2.col
FROM etape_1 AS e1
JOIN etape_2 AS e2 ON e1.id = e2.id
6.2 RequĂȘtes : UNNEST() (Types Nested)

ProblĂšme : Comment requĂȘter une colonne ARRAY (2.3) (une liste) ?

La Fonction UNNEST() (Aplatir)

UNNEST() est l'opérateur (similaire à FLATTEN) qui prend un ARRAY et le transforme en lignes (Rows).

Table "Commandes" (1 Ligne) :
{
  "commande_id": "1001",
  "lignes": [
    { "produit": "A", "qte": 2 },
    { "produit": "B", "qte": 1 }
  ]
}
RequĂȘte (UNNEST)
SELECT
    commande_id,
    
    # (Accéder à la ligne 'unnestée')
    ligne.produit,
    ligne.qte
    
FROM
    `ma_table.commandes`
    
# (Le "JOIN" spécial pour "dénormaliser" (aplatir) l'ARRAY)
CROSS JOIN
    UNNEST(lignes) AS ligne
Résultat (2 Lignes)
commande_id | produit | qte
----------------------------
1001        | A       | 2
1001        | B       | 1
6.3 RequĂȘtes : UDF (User-Defined Functions)

BigQuery permet de créer des fonctions personnalisées (UDFs) (réutilisables) directement en SQL ou en JavaScript.

UDF (SQL)
-- 1. Définir la fonction (temporaire)
CREATE TEMP FUNCTION multiplier_par_deux(x INT64) AS (
  x * 2
);

-- 2. L'utiliser
SELECT
  valeur,
  multiplier_par_deux(valeur) AS double
FROM
  ma_table
UDF (JavaScript)

(Pour la logique complexe : ex: Regex, JSON parsing complexe).

CREATE TEMP FUNCTION extraire_email(str STRING)
RETURNS STRING
LANGUAGE js -- (Langage = JavaScript)
AS r"""
  // (Code JS)
  try {
    let email = str.match(/[\w\.-]+@[\w\.-]+/);
    return email[0];
  } catch (e) {
    return null;
  }
""";

SELECT
  texte_log,
  extraire_email(texte_log) AS email
FROM
  mes_logs
7.1 Optimisation : Partitioning (Partitionnement)

C'est la principale technique d'optimisation (Coût & Vitesse) de BigQuery.

Le Partitionnement (Partitioning) est une "division" (physique) de la table en "sous-tables" (partitions) basée sur une colonne (généralement la Date).

ProblĂšme (Table 5 To, 3 ans d'historique)
-- (RequĂȘte pour hier : 10 Go)
SELECT * FROM ma_table_5To WHERE date = '2025-11-09'
-- (BQ (On-Demand) scanne les 5 To ! (Coût $$$))
Solution (Partitionnement par Temps)
-- (Créer la table partitionnée par jour)
CREATE TABLE ma_table_5To ( ... )
PARTITION BY DATE(timestamp_col)

Flux (RequĂȘte sur table partitionnĂ©e) :

SELECT * FROM ma_table_5To WHERE date(timestamp_col) = '2025-11-09'

Résultat : BigQuery (Dremel) ne scanne que la partition "2025-11-09" (10 Go). (Coût réduit de 99%).

Types
  • Par Temps (DĂ©faut) : (Jour/Heure/Mois/An) (_PARTITIONTIME).
  • Par Colonne (Entier) : (ex: customer_id).
7.2 Optimisation : Clustering

Le Clustering (similaire à Snowflake 3.3 ou Z-Order 3.3) est une optimisation "secondaire" (utilisée aprÚs le Partitionnement).

Le Clustering trie (sort) physiquement les données à l'intérieur d'une partition, en se basant sur une (ou plusieurs) colonne(s) (ex: region, user_id).

Exemple (Partition + Cluster)
CREATE TABLE ma_table ( ... )
PARTITION BY DATE(date_commande)
CLUSTER BY region
Flux (RequĂȘte)
SELECT * FROM ma_table
WHERE date_commande = '2025-11-09'
  AND region = 'France'
  1. Étape 1 (Partitioning) : BQ ne lit que la partition "2025-11-09".
  2. Étape 2 (Clustering) : À l'intĂ©rieur de cette partition, BQ (grĂące au tri) ne lit que les blocs (micro-partitions) oĂč region = 'France'.

Résultat : Optimisation (Coût/Vitesse) encore meilleure.

7.3 Outils : BQML & BI Engine
BigQuery ML (BQML)

BQML permet aux Analystes SQL d'entraßner (train) et d'exécuter (predict) des modÚles de Machine Learning (ML) directement en SQL, sans Python/Databricks.

-- 1. Entraßner un modÚle de Régression (Prédiction)
CREATE OR REPLACE MODEL `project.dataset.sales_model`
OPTIONS(model_type='LINEAR_REG') AS
SELECT
  sales_jour_J_plus_1 AS label, -- (Ce qu'on veut prédire)
  meteo,
  jour_semaine
FROM
  `dataset.training_data`;
  
-- 2. Prédire (en SQL)
SELECT
  *
FROM
  ML.PREDICT(MODEL `project.dataset.sales_model`,
    (SELECT ... FROM `dataset.future_data`));
BI Engine

ProblĂšme : BQ (On-Demand) est rapide (secondes), mais pas assez rapide pour les Dashboards BI (qui demandent une latence < 1 seconde).

Solution : BI Engine (BigQuery Accelerator).

C'est un service de cache In-Memory (en RAM), intelligent et managé.

(Utilisateur) -> [Looker / Power BI]
    │
    │ (RequĂȘte)
    ▌
[ BI Engine (Cache RAM) ]
    │ (Hit) -> (RĂ©ponse < 1 sec)
    │
    │ (Miss)
    ▌
[ BigQuery (Slots) ]
    │ (RĂ©ponse > 3 sec)
    └ (Met en cache)

AccĂ©lĂšre massivement les requĂȘtes BI (Dashboards) en mettant en cache les rĂ©sultats (et les donnĂ©es "chaudes") en RAM.