Partitionnement et Clustering

Le partitionnement et le clustering sont les deux leviers les plus puissants pour réduire les coûts BigQuery. Bien configurés, ils peuvent réduire les coûts de 90%+.

Types de partitionnement

TypeUse caseLimite
Time-unit (DATE/TIMESTAMP)Données temporelles (logs, events)4,000 partitions
Integer rangeIDs, codes numériques10,000 partitions
Ingestion timeDonnées sans colonne date fiable4,000 partitions

Erreur frequente

Choisir le mauvais type de partitionnement. Si vos requetes filtrent toujours par date, partitionnez par date. Si elles filtrent par customer_id, utilisez le range partitioning. Analysez vos patterns de requetes avant de creer la table.

Partition par date (le plus courant)

-- Création avec partition
CREATE TABLE `project.dataset.events`
(
  event_id STRING,
  user_id INT64,
  event_type STRING,
  event_timestamp TIMESTAMP,
  event_date DATE,
  payload STRING
)
PARTITION BY event_date
OPTIONS (
  partition_expiration_days = 365,
  require_partition_filter = TRUE  -- Force le filtrage !
);

Granularité de partition

-- Par jour (défaut)
PARTITION BY event_date

-- Par mois (moins de partitions, moins de pruning)
PARTITION BY DATE_TRUNC(event_date, MONTH)

-- Par heure (pour très gros volumes)
PARTITION BY TIMESTAMP_TRUNC(event_timestamp, HOUR)

Partition par range (integer)

-- Partition par customer_id
CREATE TABLE `project.dataset.orders`
(
  order_id STRING,
  customer_id INT64,
  amount NUMERIC
)
PARTITION BY RANGE_BUCKET(customer_id, GENERATE_ARRAY(0, 1000000, 10000));
-- 100 partitions de 10,000 IDs chacune

Clustering

Le clustering trie les données à l'intérieur des partitions pour accélérer les filtres.

-- Jusqu'à 4 colonnes de clustering
CREATE TABLE `project.dataset.events`
PARTITION BY event_date
CLUSTER BY country, event_type, user_id;
-- L'ordre compte : clusterez par les colonnes les plus filtrées en premier
AspectPartitionnementClustering
MécanismeSépare en fichiers distinctsTrie à l'intérieur
Colonnes1 seuleJusqu'à 4
Coût estiméExact (avant exécution)Variable (après exécution)
Types supportésDATE, TIMESTAMP, INTEGERSTRING, INT, DATE, BOOL, etc.

A retenir

Le clustering ne garantit pas de reduction de cout a l'avance (estimation variable), mais reduit quasi-toujours les bytes scannes. Combinez-le avec le partitionnement pour un effet maximal.

Combinaison Partition + Clustering

-- Configuration optimale pour une table d'events
CREATE TABLE `project.dataset.events`
(
  event_id STRING,
  event_date DATE,
  country STRING,
  event_type STRING,
  user_id INT64,
  payload JSON
)
PARTITION BY event_date
CLUSTER BY country, event_type
OPTIONS (
  partition_expiration_days = 730,
  require_partition_filter = TRUE
);

-- Requête optimisée
SELECT COUNT(*)
FROM `project.dataset.events`
WHERE event_date = '2025-01-15'     -- Partition pruning
  AND country = 'FR'                 -- Cluster pruning
  AND event_type = 'purchase';       -- Cluster pruning

Bonnes pratiques

  • Toujours partitionner les tables de plus de 1 GB
  • require_partition_filter = TRUE pour éviter les full scans accidentels
  • Clusterer par les colonnes les plus filtrées (en premier dans la liste)
  • Eviter trop de partitions (< 4,000 pour les dates)
  • partition_expiration_days pour supprimer automatiquement les vieilles données
  • Re-clusterer si les données changent beaucoup (BigQuery le fait automatiquement en arrière-plan)

Decision concrete

Pour une nouvelle table : partitionnez par la colonne de date utilisee dans 80% des requetes, puis clusterez par les 2-3 colonnes les plus filtrees. Testez avec un echantillon avant de migrer toutes les donnees.
Jonathan Kini

Jonathan Kini

J'aide les équipes data à réduire et maîtriser leurs coûts BigQuery et Snowflake, sans sacrifier la performance. 8 ans de terrain, de la startup aux environnements data à grande échelle.