DuckDB per Analisi Ad-Hoc: Trasformare Migliaia di CSV in una Dashboard
Amazon Seller Central genera dati a un ritmo che supera gli strumenti della maggior parte degli analisti. Report sul traffico, dati di conversione, riepiloghi sulla salute dell'inventario, esportazioni delle performance aziendali, analisi delle campagne pubblicitarie – ciascuno consegnato come file CSV o TSV, accumulandosi nel corso di mesi e anni in directory contenenti migliaia di file. La risposta standard è importare tutto in un database. In realtà, però, avviare, mantenere e interrogare un'istanza PostgreSQL per un carico di lavoro analitico fondamentalmente a lettura intensa e schema variabile introduce più overhead operativo di quanto il problema stesso giustifichi.
Abbiamo costruito una pipeline di reportistica per un venditore Amazon che opera in cinque marketplace europei. I dati grezzi: sei anni di esportazioni Seller Central, 4.200 file, che coprono report aziendali, performance pubblicitarie, snapshot dell'inventario e registri delle commissioni FBA. L'approccio iniziale – uno schema PostgreSQL con script ETL – ha impiegato tre settimane per stabilizzarsi e richiedeva un'attenzione costante mentre Amazon rivedeva i nomi delle colonne e le strutture dei report nelle versioni API. Le query erano veloci. La manutenzione no.
DuckDB cambia quel calcolo. È un database analitico incorporato – funziona in-process insieme al codice di analisi, non richiede server, nessun daemon, nessuna stringa di connessione, e legge direttamente dai file su disco. L'interfaccia di query è SQL standard. Le caratteristiche di prestazione sono quelle di un motore colonnare ottimizzato per l'aggregazione su larga scala. Per un carico di lavoro come questo, DuckDB non è solo adeguato – è lo strumento corretto.
Cos'è DuckDB in realtà
La distinzione più importante è l'archiviazione colonnare rispetto all'archiviazione per righe. PostgreSQL organizza i dati in righe: ogni campo per un determinato record è archiviato in modo contiguo su disco. Quando si esegue SELECT revenue, units_sold FROM orders WHERE marketplace = 'DE', il database legge ogni campo per ogni riga, scarta quelli non richiesti e restituisce i due richiesti. Questo è efficiente per i carichi di lavoro transazionali – inserimento, aggiornamento e recupero di singoli record. È in gran parte inadatto alle query analitiche che aggregano su milioni di righe toccando solo pochi colonne.
DuckDB organizza i dati per colonna. Ogni valore per revenue è archiviato insieme; ogni valore per units_sold è archiviato insieme. La stessa query legge solo i due frammenti di colonna di cui ha bisogno, saltando il resto completamente. Su un dataset con quaranta colonne, questa non è un'ottimizzazione minore – riduce l'I/O di circa il 95 percento per le query analitiche tipiche. Combinata con l'esecuzione vettorializzata – elaborazione dei dati in batch di 1.024 valori alla volta usando istruzioni CPU SIMD piuttosto che una riga alla volta – DuckDB raggiunge prestazioni di query su carichi di lavoro analitici che superano regolarmente ciò che un'istanza PostgreSQL ben ottimizzata può offrire su hardware identico.
L'architettura incorporata è ugualmente importante. Non c'è nessun round-trip di rete, nessun overhead di autenticazione, nessun pool di connessioni da gestire. DuckDB apre un file o una directory, costruisce un piano di query ed esegue. Il binario è sotto i 100MB. Funziona su un laptop, all'interno di una funzione Lambda, o all'interno di uno script Python invocato da un cron job. Per le pipeline analitiche self-hosted, la superficie operativa è vicina a zero.
SQL direttamente sui file
La funzionalità che rende DuckDB pratico per i dati Seller Central in modo specifico è la scansione di file basata su glob. Una singola istruzione SQL interroga migliaia di CSV simultaneamente:
SELECT
date_trunc('month', "Date") AS month,
SUM("Units Ordered") AS units,
SUM("Ordered Product Sales") AS revenue
FROM read_csv_auto('/data/seller-central/business-reports/*.csv')
GROUP BY 1
ORDER BY 1;
read_csv_auto inferisce lo schema dal contenuto del file – campiona le righe, rileva i tipi di colonna, gestisce diversi delimitatori e unisce gli schemi tra i file dove i set di colonne differiscono. Per i dati Seller Central, dove Amazon ha rivisto i nomi delle colonne almeno quattro volte negli ultimi tre anni, questo è importante. La query viene eseguita su qualunque file esista nella directory al momento dell'esecuzione, senza passaggio di importazione, nessuna migrazione dello schema e nessuna cache obsoleta da invalidare.
Per le esportazioni TSV dalla console pubblicitaria, lo stesso approccio si applica con un suggerimento di formato esplicito:
FROM read_csv('/data/advertising/*.tsv', delim=' ', header=true)
Questa non è una funzionalità di convenienza. È un modello mentale diverso per lavorare con i dati basati su file: il file system diventa il database. Lo schema viene inferito, non dichiarato. Le query si compongono attraverso i confini dei file senza alcun passaggio di pre-elaborazione. Per l'analisi ad-hoc, dove la domanda cambia più velocemente di quanto una pipeline ETL possa essere aggiornata, questa architettura è il default corretto.
Caratteristiche delle prestazioni
Sul nostro dataset di riferimento – 4.200 file, circa 2,8 GB non compressi – un'aggregazione completa dei ricavi raggruppata per marketplace, ASIN e mese si completa in 4,1 secondi su un laptop standard (Apple M2, 16 GB RAM). La query PostgreSQL equivalente, su dati importati e indicizzati, si completa in 2,8 secondi. Ma quel confronto esclude l'importazione iniziale di quaranta minuti, le migrazioni dello schema richieste ogni volta che Amazon cambia il nome di una colonna e il costo di manutenzione ETL continuo. Sul costo operativo totale, DuckDB vince decisamente per questo carico di lavoro.
Se le prestazioni delle query diventano un collo di bottiglia – tipicamente su scala multi-terabyte – DuckDB legge Parquet nativamente, e convertire i file CSV esistenti in Parquet è un'operazione una tantum:
COPY (FROM read_csv_auto('/data/**/*.csv'))
TO '/data/consolidated.parquet'
(FORMAT PARQUET);
Le query successive sul file Parquet vengono eseguite da 8 a 12 volte più velocemente rispetto ai CSV originali. Parquet archivia statistiche sulle colonne – valori minimi e massimi per gruppo di righe – che DuckDB usa per saltare interi sezioni di dati senza leggerli. Un filtro su marketplace = 'DE' su un file Parquet ordinato può leggere meno del dieci percento dei dati su disco. Questo predicate pushdown non è disponibile sui file CSV flat.
Costruire una dashboard standalone con Chart.js
L'output delle query DuckDB sono dati. La domanda pratica è cosa farne. Per la reportistica interna nelle piccole e medie operazioni Amazon, un file HTML standalone alimentato da Chart.js è spesso più utile di una dashboard hosted – nessun server da eseguire, nessuna credenziale da gestire, nessuna istanza Superset o Metabase da mantenere.
La pipeline funziona in tre passaggi. Prima, DuckDB esporta i risultati delle query in JSON:
COPY (
SELECT
strftime(date_trunc('week', "Date"), '%Y-%m-%d') AS week,
SUM("Units Ordered") AS units,
SUM("Ordered Product Sales") AS revenue
FROM read_csv_auto('/data/**/*.csv')
GROUP BY 1 ORDER BY 1
) TO 'weekly.json' (FORMAT JSON, ARRAY true);
Secondo, uno script Python legge quei file JSON e incorpora i dati direttamente in un template HTML che fa riferimento a Chart.js via CDN. Terzo, il file HTML si apre in un browser senza necessità di un server web.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Seller Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="revenue"></canvas>
<script>
const rows = /* JSON_DATA_HERE */;
new Chart(document.getElementById('revenue'), {
type: 'line',
data: {
labels: rows.map(r => r.week),
datasets: [{ label: 'Revenue', data: rows.map(r => r.revenue), tension: 0.3 }]
}
});
</script>
</body>
</html>
Il risultato è un file autocontenuto che può essere condiviso via email, inserito su un bucket S3 privato, o aperto direttamente da una directory locale. Per i team operativi che hanno bisogno di reportistica settimanale senza il costo dell'infrastruttura della dashboard live, questo approccio è pragmatico e manutenibile. La dashboard si rigenera eseguendo uno script shell: DuckDB interroga i CSV, Python costruisce l'HTML, fatto. Nessuna infrastruttura, nessun costo ricorrente, nessuna superficie di manutenzione.
Quando DuckDB batte PostgreSQL
DuckDB non è un sostituto di PostgreSQL. Il confronto è significativo solo quando il carico di lavoro è genuinamente analitico – grandi scansioni, aggregazioni, group-by – e i dati vengono principalmente letti piuttosto che scritti. PostgreSQL vince decisamente sulle scritture concorrenti, l'integrità referenziale, il controllo degli accessi a livello di riga e i requisiti operativi completi di un'applicazione di produzione. È la scelta corretta per un sistema multi-utente dove i record vengono inseriti, aggiornati e interrogati dal codice dell'applicazione.
DuckDB vince quando:
- I dati esistono già come file su disco, senza alcun passaggio di importazione pianificato
- Lo schema non è completamente noto in anticipo, o cambia frequentemente
- Le query sono ad-hoc e i pattern di accesso non possono essere previsti in anticipo
- Il costo operativo di un server database non è giustificato dalla longevità del progetto o dalla scala
I dati di Amazon Seller Central soddisfano tutti e quattro i criteri con precisione. Lo schema cambia ad ogni release di Seller Central. I file esistono già localmente dopo l'esportazione. Le domande aziendali cambiano settimana per settimana a seconda di cosa si sta ottimizzando. E l'alternativa – una pipeline ETL PostgreSQL mantenuta – rappresenta settimane di tempo di ingegneria per un problema che DuckDB risolve in un pomeriggio.
La regola pratica: se normalmente si userebbe Excel o un notebook Jupyter per analizzare questi dati, usare DuckDB invece. L'SQL è più espressivo, le prestazioni sono di ordini di grandezza migliori per qualsiasi cosa oltre poche migliaia di righe, e l'architettura basata su file significa che i dati rimangono dove sono già.
Approfondimenti Correlati
- tva-fetch | Come la Proprietà Completa dei Dati Trasforma le Operazioni di Vendita su Amazon
- Costruire un'Infrastruttura Dati Pronta per la Produzione per i Venditori Amazon: Introduzione a tva-fetch
- Traefik Reverse Proxy: La Guida Completa al Self-Hosting per HTTPS e Automazione SSL
- Self-Hosting di Windmill su Ubuntu: Tutorial Completo di Configurazione Docker con Risoluzione dei Problemi PostgreSQL