> ## Content Index
> Fetch the complete content index at: https://www.idriss-benbassou.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Partitionnement Athena : diviser les coûts par 10 (partitions S3)
- URL: https://www.idriss-benbassou.com/partitionnement-athena-partitions-s3-couts/
- Published: 2026-08-19T22:15:55.000Z
- Updated: 2026-08-19T22:15:55.000Z
- Author: Idriss BENBASSOU
- Tags: AWS, #rating-2

Sur Athena, il y a deux façons de payer moins, lire moins de colonnes et lire moins de lignes. On transformant les csv on [Parquet](https://www.idriss-benbassou.com/athena-csv-vs-parquet-ctas-donnee-scannee/) on a réglé les colonnes. Pour les lignes, c'est le partitionnement, le levier le plus rentable de toute [la formation AWS](https://www.idriss-benbassou.com/formation-aws/). Et spoiler, on va enfin vraiment parler de la colonne mystère `partition_0` qui traîne depuis [l'article crawler](https://www.idriss-benbassou.com/glue-data-catalog-crawler-data-lake-s3/).

## C'est quoi une partition

Une partition, c'est un sous-dossier dans S3, nommé au format `cle=valeur`.

```
clean/commandes_part/
├── mois=2026-01/fichier.parquet
├── mois=2026-02/fichier.parquet
├── mois=2026-03/fichier.parquet
└── ...

```

L'intérêt, quand une requête filtre sur la clé de partition (`WHERE mois = '2026-03'`), Athena ne lit que le dossier qui matche et ignore tous les autres. C'est le partition pruning. Pas de filtre magique, pas d'index, juste des dossiers bien nommés.

En entreprise, on partitionne quasi toujours par date. Les requêtes métier filtrent presque toutes sur une période ("le CA du mois", "les ventes de la semaine"), donc chaque requête ne paye que les jours ou les mois qu'elle regarde. Sur un historique de 3 ans requêté au mois, c'est 1/36e de la donnée scannée.

> Un lake sans partition, c'est une bibliothèque sans rayons. Chaque question oblige à lire tous les livres.

## Partitionner avec CTAS

On repart de la table Parquet de l'article précédent et on la reconstruit partitionnée par mois. Toujours en une requête CTAS, avec l'option `partitioned_by`.

```sql
CREATE TABLE ecommerce_clean.commandes_part
WITH (
    format = 'PARQUET',
    write_compression = 'SNAPPY',
    external_location = 's3://ibdata-datalake-formation/clean/commandes_part/',
    partitioned_by = ARRAY['mois']
) AS
SELECT
    commande_id,
    client_id,
    produit_id,
    quantite,
    montant,
    date_commande,
    statut,
    date_format(date_commande, '%Y-%m') AS mois
FROM ecommerce_clean.commandes;

```

Attention au détail qui fait échouer tout le monde la première fois, **la colonne de partition doit être la dernière du SELECT**. Athena est strict là-dessus, `mois` en plein milieu de la liste et la requête plante.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-41.png)

On va voir dans S3, le préfixe `clean/commandes_part/` contient maintenant un dossier par mois.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-42.png)

## La preuve par la donnée scannée

Même requête, une fois sur la table non partitionnée, une fois sur la partitionnée.

```sql
-- Table non partitionnée : tout est scanné
SELECT COUNT(*), ROUND(SUM(montant), 2) AS ca
FROM ecommerce_clean.commandes
WHERE date_format(date_commande, '%Y-%m') = '2026-03';

-- Table partitionnée : seul le dossier mois=2026-03 est lu
SELECT COUNT(*), ROUND(SUM(montant), 2) AS ca
FROM ecommerce_clean.commandes_part
WHERE mois = '2026-03';

```

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-44.png)

Table non partitionnée : tout est scanné

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-45.png)

Table partitionnée : seul le dossier mois=2026-03 est lu

Compare les deux chiffres. La première lit toute la table, la seconde lit un sixième (un mois sur six). Sur nos Ko, la différence est symbolique, mais comprendre le mécanisme est le plus important car il permet de diviser les factures sur de vrais volumes. Un historique de 3 ans partitionné par jour, requêté sur la veille, c'est plus de 1 000 fois moins de donnée scannée.

💡

Le pruning ne marche que si le filtre porte sur la colonne de partition. `WHERE mois = '2026-03'` prune, `WHERE date_commande >= DATE '2026-03-01'` ne prune pas, Athena n'a aucun moyen de savoir que les deux reviennent au même.

 Donc si une requête coute cher c'est l'un des premier aspect à vérifier

## Et la colonne partition\_0 ?

Retour sur la zone raw car [d](https://www.idriss-benbassou.com/glue-data-catalog-crawler-data-lake-s3/)[ans l'article crawler](https://www.idriss-benbassou.com/glue-data-catalog-crawler-data-lake-s3/), on avait vu que le dossier daté `2026-08-16` était détecté comme partition, mais nommé `partition_0` faute de format `cle=valeur`. La correction est maintenant évidente, il suffit de nommer les dossiers d'arrivée en bon format.

Concrètement, dans le script boto3 de l'article collecte, on change une ligne.

```python
# version 1 => avant
destination = f"raw/commandes/{aujourd_hui}/{f}"

# version 2 => aprés
destination = f"raw/commandes/date_export={aujourd_hui}/{f}"

```

Au prochain passage du crawler, la colonne s'appellera `date_export` au lieu de `partition_0`, et chaque nouvel export quotidien deviendra une partition requêtable. Un `WHERE date_export = '2026-08-16'` permettra d'avoir les données d'une journée précise sans scanner l'historique.

💡

Nb : Quand une nouvelle partition arrive dans S3, la table ne s'ajoute pas automatiquement. Trois options, relancer le crawler ou avoir un scheduler, exécuter `MSCK REPAIR TABLE` dans Athena, ou déclarer la partition avec `ALTER TABLE ADD PARTITION`. On automatisera ça dans le module orchestration. ;)

## Les pièges du partitionnement

Deux erreurs classiques à éviter.

\=> Trop de partitions car partitionner par jour ET par pays ET par produit, ça donne des milliers de dossiers avec des fichiers minuscules dedans, et Athena passe plus de temps à ouvrir des fichiers qu'à les lire. La règle simple, viser des partitions d'au moins 100 Mo, et une seule clé de partition (la date) couvre généralement 90 % des besoins.

\=> Partitionner une petite table car en dessous de quelques centaines de Mo, le partitionnement complique tout pour rien. Nos tables clients et produits resteront non partitionnées, et c'est très bien.

## La checklist finale

- \[ \] Table commandes\_part créée avec le CTAS partitionné, la colonne de partition en dernier.
- \[ \] Les dossiers mois= visibles dans S3.
- \[ \] La comparaison faite, le filtre sur la partition scanne une fraction de la table.
- \[ \] Le script de collecte adapté au format date\_export=.

### Combien ça coûte ?

Moins d'un centime. Le CTAS scanne la table Parquet une fois, et les partitions ne coûtent rien en elles-mêmes.

## La suite ?

Le lake est requêtable et optimisé, mais la zone clean s'est construite à coups de CTAS manuels, avec les doublons toujours dedans. Dans le prochain article, on industrialise le passage raw vers clean avec **Glue ETL**, déduplication, règles de qualité, et un job qu'on pourra rejouer et planifier.

## Aller plus loin

Le programme complet du parcours est sur la page de [la formation AWS](https://www.idriss-benbassou.com/formation-aws/).

Tu prépares la certification AWS Certified Data Engineer Associate (DEA-C01) ? Le partitionnement et l'optimisation des coûts Athena tombent à chaque session. Pour t'entraîner, j'ai créé des questions d'examen blanc en français.

👉 [S'entraîner sur DataCertification.fr](https://datacertification.fr/certifications?ref=idriss-benbassou.com)

Tu veux que je t'accompagne sur ton projet data (AWS, Snowflake, dbt, modélisation, coûts) ?

👉 [Réserver un appel de 30 minutes](https://calendly.com/idriss-benbassou-datavio/30min?ref=idriss-benbassou.com)

## Questions fréquentes

#### C'est quoi une partition dans Athena ?

Un sous-dossier S3 nommé au format cle=valeur (par exemple mois=2026-03). Quand une requête filtre sur la clé de partition, Athena ne lit que les dossiers qui matchent, c'est le partition pruning, et la donnée scannée (donc la facture) baisse d'autant.

#### Comment partitionner une table avec Athena ?

Avec un CTAS et l'option partitioned\_by. La colonne de partition doit être la dernière du SELECT, c'est l'erreur la plus fréquente. Pour les nouvelles données qui arrivent dans S3, il suffit de nommer les dossiers en cle=valeur et de déclarer les partitions (crawler, MSCK REPAIR TABLE ou ADD PARTITION).

#### Par quoi partitionner ses tables ?

Par date dans la grande majorité des cas, parce que les requêtes métier filtrent presque toutes sur une période. La granularité (jour, mois) dépend du volume, l'objectif étant des partitions d'au moins 100 Mo.

#### Pourquoi ma requête scanne toute la table malgré les partitions ?

Parce que le filtre ne porte pas sur la colonne de partition. WHERE mois = '2026-03' déclenche le pruning, WHERE date\_commande >= '2026-03-01' non, même si le résultat est identique. Le filtre doit utiliser la clé de partition telle quelle.

#### Peut-on avoir trop de partitions ?

Oui. Des milliers de petites partitions créent une multitude de petits fichiers, et l'ouverture des fichiers coûte plus cher que leur lecture. La cible, des partitions d'au moins 100 Mo, et une seule clé de partition suffit dans la plupart des projets.