Un negozio PrestaShop in produzione da cinque anni pesa raramente meno di 6 GB di database. Molti superano i 12 GB. Non è il catalogo che esplode — un catalogo di 10.000 prodotti con combinazioni, immagini e SEO completa sta sotto il gigabyte. Ciò che gonfia il database sono le tabelle zavorra: tabelle tecniche che PrestaShop alimenta in continuazione e che nessun processo nativo pulisce. Dopo cinque anni rappresentano spesso il 70-90% del peso totale del database.
Questo articolo mappa le tabelle colpevoli, fornisce le query SQL per misurare il guadagno potenziale e spiega come impostare una politica di retention duratura senza rompere il negozio. Non una checklist da rivista — la versione che applichiamo realmente in produzione.
Perché un database PrestaShop si gonfia silenziosamente
PrestaShop non ha un garbage collector. Tutte le tabelle che registrano eventi — ricerche interne, connessioni, carrelli abbandonati, log, metadati orfani — crescono linearmente, a volte esponenzialmente, senza che nessun meccanismo nativo inneschi una pulizia.
Concretamente, su un negozio con 2.000 visitatori al giorno:
ps_statssearchriceve 300-800 righe al giorno (ogni ricerca interna, anche vuota).ps_connectionseps_connections_pageregistrano ogni visita e ogni pagina vista. Calcolate 5.000-15.000 righe al giorno.ps_guestcrea un record per ogni visitatore non autenticato.ps_cartconserva tutti i carrelli — compresi quelli abbandonati — per sempre. Su alcuni negozi troviamo il 90% di carrelli vuoti datati 2018.ps_logcattura tutti gli errori e gli eventi admin.
Moltiplicate per 365 giorni e 5 anni: parliamo di decine di milioni di righe per un valore di business pari a zero. Il peso bruto non è il problema peggiore. Il vero costo è altrove.
Il costo nascosto delle tabelle zavorra
1. Performance delle query
InnoDB carica gli indici in memoria (buffer pool). Quando tabelle tecniche da diversi GB monopolizzano il buffer, le tue query di catalogo, carrello e ordine diventano più lente. L’LCP di una scheda prodotto può richiedere 200-400 ms supplementari solo a causa della pressione memoria su MySQL.
2. Backup e ripristino
Un dump mysqldump da 12 GB impiega 30-60 minuti secondo il disco. Il ripristino può richiedere 2-4 ore. Se il backup automatico del tuo hosting supera la finestra oraria, comincia a fallire in silenzio. Molti negozi scoprono di non avere più un backup valido il giorno di un incidente.
3. Migrazioni bloccate
Migrare un negozio da 12 GB in PHP 8.2 verso un nuovo server, o verso PrestaShop 9, richiede di trasferire il dump via rsync, ripristinare, testare. Il peso moltiplica ogni operazione. Le migrazioni “semplici” diventano progetti di diversi giorni.
4. Moduli di terze parti che appesantiscono
Alcuni moduli di statistiche, marketing o connettori ERP creano tabelle proprie e le lasciano crescere indefinitamente. ps_netreviews_, ps_advancedstats_, ps_mailchimp_ sono sospetti frequenti. Un audit rivela spesso una tabella da 2 GB lasciata da un modulo disinstallato due anni fa.
Audit: quanto pesa davvero il tuo database
Prima di qualsiasi pulizia, si misura. Questa query elenca le tabelle del tuo database ordinate per dimensione decrescente:
SELECT
table_name AS 'Table',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)',
table_rows AS 'Rows'
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC
LIMIT 30;
In genere ottieni una classifica simile a:
ps_statssearch— 1,8 GBps_connections_page— 1,2 GBps_pagenotfound— 800 MBps_connections— 600 MBps_log— 400 MBps_cart— 350 MBps_guest— 300 MBps_cart_rule+ps_cart_cart_rule— 250 MB
Nota che ps_product, ps_product_lang, ps_orders compaiono raramente nella top 10. I dati di business reali sono minoritari in un database PrestaShop datato.
Mappatura delle tabelle zavorra e politica di retention
ps_statssearch — le ricerche interne
Questa tabella registra ogni parola digitata nella barra di ricerca. Conservare lo storico oltre i 90 giorni non ha alcun interesse analitico: le tendenze di ricerca del 2019 non illuminano niente nel 2026. Politica consigliata: retention 90 giorni.
-- Audit
SELECT COUNT(*) AS total, MIN(date_add) AS plus_ancien
FROM ps_statssearch;
-- Eliminazione oltre i 90 giorni
DELETE FROM ps_statssearch
WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY);
ps_connections e ps_connections_page — lo storico delle visite
Se usi GA4 o Matomo, queste tabelle sono ridondanti. PrestaShop le riempie per il suo modulo di statistiche interno che nessuno consulta. Politica: retention 30 giorni, o 0 se hai uno strumento esterno.
ps_pagenotfound — i 404
Utile per identificare i link rotti e programmare redirect 301. Ma dopo il trattamento, lo storico non serve più. Politica: retention 60 giorni, dopo aver estratto i 404 ricorrenti.
ps_cart — i carrelli abbandonati
Sottile. I carrelli recenti servono al retargeting e ai recuperi. Oltre i 90 giorni, un carrello abbandonato è statisticamente perso. Politica: conservare 90 giorni, ma non toccare mai i carrelli legati a ordini (tabella join ps_orders.id_cart).
-- Eliminazione sicura: solo i carrelli SENZA ordine associato
DELETE c FROM ps_cart c
LEFT JOIN ps_orders o ON o.id_cart = c.id_cart
WHERE o.id_cart IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 90 DAY);
ps_guest — i visitatori non autenticati
Legata a ps_customer e ps_connections. Pulizia con cautela: un guest convertito in customer deve essere preservato. Politica: eliminare i guest senza customer e senza connessione recente.
ps_log — i log admin
Utili per il debug recente, senza valore oltre un mese. Politica: retention 30 giorni.
Metadati orfani
Quando elimini un prodotto, alcune tabelle correlate conservano righe orfane: ps_image, ps_feature_product, ps_specific_price, ps_product_attachment. Idem per le categorie, i produttori, i fornitori eliminati. Queste righe non servono a niente e falsano le join.
-- Esempio: ps_image orfane
SELECT i.id_image FROM ps_image i
LEFT JOIN ps_product p ON p.id_product = i.id_product
WHERE p.id_product IS NULL;
La trappola del DELETE in produzione
Eliminare un milione di righe in un’unica query su una tabella InnoDB bloccata dal tuo admin e dal tuo front, significa garantirsi un crash. Il binary log esplode, la replica si stacca, il server può andare in swap.
La regola assoluta: eliminare a lotti di 5.000-10.000 righe massimo, con una pausa di 100 ms tra ogni lotto.
-- Ciclo di eliminazione a lotti (pseudo-codice)
DO WHILE rows_affected > 0:
DELETE FROM ps_statssearch
WHERE date_add < DATE_SUB(NOW(), INTERVAL 90 DAY)
LIMIT 5000;
SLEEP 0.1;
END DO;
E sistematicamente: dry-run prima di execute. Vuoi sapere quante righe spariranno e quanto spazio recupererai prima di cliccare.
Automatizzare la retention: la strategia corretta
Fare la pulizia manualmente una volta e dimenticarsene non serve a nulla — il database tornerà a gonfiarsi. La retention deve essere continua e automatica:
- Cron giornaliero che esegue la politica di retention di ogni tabella.
- Token di sicurezza affinché il cron non sia attivabile dall’esterno.
- Log di esecuzione per tracciare ciò che è stato eliminato.
- Notifica in caso di errore o anomalia (volume di eliminazione anomalo).
- OPTIMIZE TABLE settimanale sulle tabelle pulite per recuperare spazio disco (altrimenti InnoDB conserva lo spazio allocato).
Il nostro modulo dfcleanup: il metodo pacchettizzato
Implementare questa strategia a mano richiede due o tre giorni di sviluppo e altrettanti di test. Il nostro modulo dfcleanup per PrestaShop 8 e 9 industrializza tutto il metodo descritto qui:
- Sei cleaner specializzati: ricerche, carrelli, log, statistiche, metadati orfani, immagini orfane. Ciascuno con la propria retention configurabile.
- Tre modalità: Audit (sola lettura), Dry-run (simulazione tracciata), Execute (eliminazione a lotti di 5.000 righe).
- Guadagno in MB calcolato prima dell’azione, per cleaner e totale.
- Cron protetto da token, pronto all’uso.
- Log dettagliati e compatibilità con PrestaShop 8 e 9.
A 19 €, eviti le query DELETE a mano e installi una politica di retention duratura. Confrontato con il tempo di sviluppo e il costo di un incidente DBA, è uno dei moduli con il miglior ROI del catalogo.
FAQ
Bisogna fare un OPTIMIZE TABLE dopo ogni DELETE?
No, non dopo ogni DELETE — è costoso in I/O e blocca la tabella. Una volta a settimana o al mese, in orario di scarso traffico, sulle tabelle che hanno subito una pulizia massiccia. OPTIMIZE TABLE recupera lo spazio disco che InnoDB non libera naturalmente dopo l’eliminazione.
La pulizia può influenzare la SEO o le statistiche?
Nessun impatto SEO: le tabelle pulite sono tecniche (ricerche interne, connessioni, log), non il catalogo né gli URL. Per le statistiche, se usi GA4 o Matomo, i tuoi dati sono memorizzati lì — il database PrestaShop è ridondante. Se usi le statistiche native di PS, configura una retention più lunga (180 giorni ad esempio).
Quale retention per i carrelli abbandonati?
90 giorni bastano ampiamente. Gli strumenti di recupero carrello (mail, retargeting) si attivano nelle 24-72 ore. Oltre i 90 giorni, la probabilità di recupero è statisticamente nulla. E non elimini mai un carrello convertito in ordine — la join ps_orders.id_cart protegge questo dato.
Quanto guadagno aspettarsi concretamente?
Su un negozio attivo da 5 anni, con 2.000 visitatori al giorno, misuriamo in media una riduzione del 60-80% del database al primo passaggio. Un negozio da 12 GB scende a 3 o 4 GB. I passaggi successivi stabilizzano il database a un livello vicino al “peso reale di business”.
Il modulo è compatibile multi-negozio?
Sì. I cleaner rispettano il perimetro multi-shop quando pertinente (carrelli, ricerche per negozio). Le tabelle globali (log, connessioni) sono pulite globalmente.
Per approfondire
Il debito di database è una delle tre principali fonti di degrado delle performance a lungo termine di un negozio PrestaShop, insieme ai moduli di terze parti obsoleti e alle immagini mal ottimizzate. Vedi anche la nostra checklist Core Web Vitals 2026 per il resto del quadro, e la guida PrestaShop 9 vs 8 se prepari una migrazione: alleggerire il database prima della migrazione può dividere per 5 il tempo di switch.
