Le format Parquet et l’écosystème DuckDB: l’essayer c’est l’adopter!

Rencontres R 2025 - Mons

Insee

12/05/2025

Pourquoi le format Parquet ?

Enjeux

  • Le choix d’un format de données répond à un arbitrage entre plusieurs critères :
    • Public cible
    • Finalité (traitement, analyse, diffusion)
    • Volumétrie
    • Interopérabilité

Formats traditionnels

  • Formats de données adhérents à un langage (sas7bdat, RDS, fst, etc.)
    • Non-interopérables -> à éviter !
  • Le format CSV
    • Interopérable et simple d’utilisation
    • Pas de gestion des méta-données
    • Peu adapté aux données volumineuses

Limites du CSV

  • Des performances limitées
    • Stockage : non-compressé -> espace disque élevé
    • Lecture : “orienté-ligne” -> performances faibles

  • Pas de typage des données à l’écriture du fichier
    • Demande expertise et précaution à la lecture
    • Exemple: 01004 pour le code commune d’Ambérieu-en-Bugey

Les avantages du format Parquet

Un format léger

  • Stockage :
    • Compression : entre 5 et 20 fois plus léger qu’un CSV

Exemple: Recensement de la Population

  • Ficher détail : 20 millions de lignes, 92 variables
    • CSV: > 4Go
    • Parquet: < 500Mo

Un format efficace

  • Lecture :
    • Jusqu’à 34x plus rapide qu’un CSV
  • “Orienté colonne”
    • Optimisé pour les traitements analytiques
    • Limite la quantité de données à mettre en mémoire
    • Conçu pour être écrit une fois mais lu fréquemment

Un format universel et fiable

  • Gestion native des méta-données
    • Définition automatique d’un schéma (noms, types)
    • Mise à disposition plus robuste
  • Interopérable
  • Open-source
  • Non lisible par un humain mais de plus en plus de visualiseurs en ligne

Parquet : un format plébiscité

Tout un écosystème autour de Parquet:

  • Des formats associés : Iceberg, Delta
  • Des acteurs importants s’appuient dessus:

Parquet: quel usage à l’Insee ?

  • Mise à disposition interne de données: format privilégié
  • Diffusion: pour les données lourdes
  • Permis d’utiliser pour de la valorisation de données administratives
    • Fin de l’hésitation entre tidyverse et data.table
    • Fin de la guéguerre /

La preuve !

Exploiter un fichier Parquet

Enjeu

  • Parquet ne résout pas tout
    • L’espace disque est optimisé
    • Les données décompressées doivent passer en RAM
  • Le framework adapté dépend de la volumétrie
    • Pour la plupart des besoins : Arrow et DuckDB
    • Pour des besoins plus avancés : Spark (de moins en moins pertinent, cf. big data is dead par Jordan Tigani)

Les frameworks

  • Deux frameworks de référence : Arrow et DuckDB
    • Orientation fichier (Arrow) VS orientation BDD (DuckDB)
  • Traitement en-mémoire optimisé
    • Orientés-colonne
    • Lazy evaluation (prochaine slide)
  • Très bonne intégration:
    • Avec le tidyverse ()
    • Avec le système de stockage S3

Exemple simple avec duckdb

library(duckdb)
con <- dbConnect(duckdb::duckdb())

# Lire un fichier Parquet
dbGetQuery(con, "
  FROM 'data/recensement.parquet'
  SELECT depcom, COUNT(*) AS n
  WHERE dep = '01'
  GROUP BY depcom
")
  • Lecture directe du fichier, SQL user friendly
  • Pas besoin d’importer en mémoire avant d’agir

Intégration avec le tidyverse

library(dplyr)
library(duckdb)

con <- dbConnect(duckdb())

rp <- tbl(con, "data/recensement.parquet")

rp |>
  filter(dep == "01") |>
  select(depcom, idlogement) |>
  group_by(depcom) |>
  summarise(n = n()) |>
  collect()
  • tbl() crée une table lazy
  • Les opérations sont retardées jusqu’à collect():
    • DuckDB optimise le plan pour gagner en performance

Les opportunités offertes par DuckDB

Intégration native à S3

  • Intégration native avec S3
    • Pour travailler sur des serveurs à l’état de l’art
    • Plutôt que sur des ordinateurs aux ressources limitées
  • On peut lire la donnée sur S3 presque comme si elle était en local
FROM 's3://bucket_name/filename.extension';
SELECT *
WHERE DEPT=='36'

DuckDB dans le navigateur

  • DuckDB WASM pour faire du DuckDB dans le navigateur :
    • Pour des dataviz réactives… dans des sites statiques !
    • Bye bye les galères de déploiement de Shiny, Streamlit
  • Simple d’usage avec Observable (et donc Quarto!)

Exemple

Cas d’usage spatial : GeoParquet

  • Parquet peut contenir des données géographiques
    • Compatible avec la norme GeoParquet
    • Lecture possible via extension SPATIAL de DuckDB
  • Permet :
    • Jointures spatiales
    • Calculs de distance
    • Récupération des données sous forme sf dans R

Conclusion: Parquet + DuckDB =

  • Simplicité et lisibilité
  • Performance
  • Interopérabilité
  • Un écosystème cloud-ready, web-ready & spatial-ready

Questions ? 🙋

Bonus

Partitionnement & tri

  • Partitionner ou ordonner les données

L’art de bien partitionner

  • Partitionner par une/des variable(s) d’intérêt si gros fichier
    • Eviter de créer de nombreux petits (< 128Mo) fichiers
  • Sinon ordonner les données avant d’écrire le fichier (cf. Eric Mauvière)

Exemple: anatomie

```{ojs}
viewof search = Inputs.select(cog, {format: x => x.LIBELLE, value: cog.find(t => t.LIBELLE == "Grasse")})

cog = db.query(`SELECT * FROM read_csv_auto("https://minio.lab.sspcloud.fr/lgaliana/data/python-ENSAE/cog_2023.csv") WHERE DEP == '06'`)
dvf = db.query(query)

db = DuckDBClient.of({})

query = `
  FROM read_parquet('https://minio.lab.sspcloud.fr/projet-formation/nouvelles-sources/data/geoparquet/dvf.parquet')
  SELECT
    CAST(date_mutation AS date) AS date,
    valeur_fonciere, code_commune,
    longitude, latitude, valeur_fonciere AS valeur_fonciere_bar
  WHERE code_commune = '${search.COM}'
`
```

Avec un peu de code supplémentaire (voir sur )