Lors de notre première requête sur Athena, on a pris le réflexe de lire la donnée scannée, et on a vu qu'un CSV se lit toujours en entier, une colonne demandée ou toutes.
Aujourd'hui, on va chercher une solution à ce problème. Et sans grande surprise, la solution sera de convertir nos commandes en Parquet, de relancer exactement les mêmes requêtes et de comparer la quantité de données scannées.
Pourquoi Parquet gagne toujours
Un CSV stocke les données ligne par ligne, comme on les lit. Parquet les stocke colonne par colonne donc Toutes les valeurs de montant ensemble, toutes les valeurs de statut ensemble etc.. etc...
Ça change trois choses.
On ne lit que ce qu'on demande. Une requête sur 2 colonnes ne lit que ces 2 colonnes, le reste du fichier n'est même pas ouvert. Sur Athena qui facture au scan, c'est le levier numéro un.
Ça compresse beaucoup mieux. Une colonne contient des valeurs du même type et souvent répétitives (pense à statut, 4 valeurs possibles sur 1 000 lignes). Compressé en Snappy, un Parquet pèse couramment 5 à 10 fois moins que le CSV d'origine. Moins d'octets stockés, moins d'octets scannés.
Les types sont embarqués. Le fichier sait que date_commande est une date et montant un décimal. On risque pas le piège des dates en string qu'on a eu dans la mise en place du crawler.

Convertir avec CTAS
Pas besoin de Spark ni d'un ETL pour convertir, Athena sait le faire seul avec un CTAS (CREATE TABLE AS SELECT). Il lit la table CSV, écrit le résultat en Parquet dans S3, et déclare la nouvelle table dans le catalogue, le tout en une requête.
On commence par créer la database de la zone clean, en SQL cette fois.
CREATE DATABASE ecommerce_clean;

Puis la conversion, avec le typage de la date au passage.
CREATE TABLE ecommerce_clean.commandes
WITH (
format = 'PARQUET',
write_compression = 'SNAPPY',
external_location = 's3://ibdata-datalake-formation/clean/commandes/'
) AS
SELECT
commande_id,
client_id,
produit_id,
quantite,
montant,
CAST(date_commande AS date) AS date_commande,
statut
FROM ecommerce_raw.commandes;

La table ecommerce_clean.commandes existe, les fichiers Parquet sont dans clean/commandes/, et le catalogue est à jour. Va jeter un œil dans S3 pour comparer les poids, le Parquet pèse plusieurs fois moins que le CSV d'origine.

On a typé la date mais gardé les doublons et les montants NULL, et c'est voulu. Le CTAS est parfait pour une conversion ponctuelle, mais le vrai chargement raw vers clean (déduplication, règles de qualité, rejouabilité) sera industrialisé avec Glue dans les prochains articles. Cette table sera alors remplacée.
La comparaison, même requête, deux formats
On lance exactement la même requête sur les deux tables et on compare la donnée scannée.
-- Sur le CSV (zone raw)
SELECT statut, COUNT(*) AS nb, ROUND(SUM(montant), 2) AS ca
FROM ecommerce_raw.commandes
GROUP BY statut;
-- Sur le Parquet (zone clean)
SELECT statut, COUNT(*) AS nb, ROUND(SUM(montant), 2) AS ca
FROM ecommerce_clean.commandes
GROUP BY statut;

Sur le CSV, Athena scanne le fichier entier, environ 48 Ko. Sur le Parquet, il ne lit que les colonnes statut et montant, compressées, soit quelques Ko. Le rapport est de l'ordre de 5 à 10 sur notre petit dataset, en prod sur des millions de lignes la différence est énorme.
On refait le test de l'article précédent, une seule colonne.
SELECT commande_id FROM ecommerce_clean.commandes LIMIT 10;
Cette fois, la donnée scannée baisse quand on demande moins de colonnes. C'est exactement le comportement qui manquait au CSV.
Dernière vérification, la date. Plus besoin de CAST.
SELECT month(date_commande) AS mois, COUNT(*) AS nb
FROM ecommerce_clean.commandes
GROUP BY 1
ORDER BY 1;
La requête qui plantait sur la zone raw passe directement. Le type est dans le fichier, tous les outils qui liront cette table (Glue, Redshift Spectrum, dbt) en profiteront sans rien configurer.
Ce que ça donne à l'échelle
Sur notre petit dataset, la différence n'est pas significatif mais en prod avec par exemple un historique de ventes de 1 To en CSV, requêté 50 fois par jour par les analystes, c'est 5 $ par requête plein scan, jusqu'à 250 $ par jour. Le même historique en Parquet pèse 100 à 200 Go, et les requêtes qui ne lisent que quelques colonnes en scannent une fraction, la facture est divisée par 10 à 50 sans toucher une seule requête.
La checklist finale
- [ ] Database ecommerce_clean créée en SQL.
- [ ] CTAS exécuté, la table commandes en Parquet existe dans clean/.
- [ ] La comparaison faite, la donnée scannée du Parquet est plusieurs fois plus faible.
- [ ] Le test une colonne et la requête month() sans CAST passés sur la table Parquet.
Combien ça coûte ?
Moins d'un centime. Le CTAS scanne le CSV une fois (facturé au minimum de 10 Mo), et le stockage Parquet ajouté se compte en Ko.
La suite ?
Parquet réduit le scan colonne par colonne. Le prochain article s'attaque à l'autre dimension, les lignes, avec le partitionnement. On réorganise le lake en dossiers date_export=, la colonne partition_0 de l'article crawler prend enfin un vrai nom, et les requêtes filtrées ne scannent plus que les partitions utiles.
Aller plus loin
Le programme complet du parcours est sur la page de la formation AWS.
Tu prépares la certification AWS Certified Data Engineer Associate (DEA-C01) ? Les formats de fichiers et l'optimisation des coûts Athena sont des sujets récurrents de l'examen. Pour t'entraîner, j'ai créé des questions d'examen blanc en français.
👉 S'entraîner sur DataCertification.fr
Tu veux que je t'accompagne sur ton projet data (AWS, Snowflake, dbt, modélisation, coûts) ?
👉 Réserver un appel de 30 minutes
Questions fréquentes
Pourquoi Parquet coûte moins cher que CSV sur Athena ?
Parce qu'Athena facture la donnée scannée et que Parquet réduit le scan deux fois. Le format colonne ne lit que les colonnes demandées, et la compression divise le poids des données par 5 à 10. La même requête scanne une fraction de ce qu'elle scannait en CSV.
C'est quoi un CTAS dans Athena ?
CREATE TABLE AS SELECT. Une requête qui lit des tables existantes, écrit le résultat dans S3 au format demandé (Parquet, ORC...), et déclare la nouvelle table dans le Glue Data Catalog. C'est le moyen le plus simple de convertir des fichiers sans ETL.
Quelle compression choisir pour Parquet ?
Snappy est le standard, un bon équilibre entre taux de compression et vitesse de lecture, et c'est le défaut d'Athena. Gzip et Zstd compressent davantage mais se lisent plus lentement, à réserver à l'archivage.
Faut-il garder les fichiers CSV après conversion en Parquet ?
Oui, en zone raw. Le CSV reste la donnée brute d'origine, le filet de sécurité intouchable. Le Parquet vit dans la zone clean et peut être régénéré depuis raw à tout moment. Une lifecycle rule peut archiver le raw en Standard-IA pour réduire son coût de stockage.
Parquet remplace-t-il le partitionnement ?
Non, les deux se combinent. Parquet réduit le scan sur l'axe des colonnes, le partitionnement le réduit sur l'axe des lignes en ne lisant que les dossiers qui matchent le filtre. Un lake bien optimisé utilise les deux.

