Ottimizzazione Database WordPress per Agenzie: Guida Pratica a Performance e Pulizia [2026]

27 agosto 202610 minPerformance

L’ottimizzazione database WordPress è il intervento di manutenzione più sottovalutato dalle agenzie che gestiscono multi-sito. Un database gonio rallenta ogni pagina, aumenta i tempi di risposta del server e compromette i Core Web Vitals. In questa guida mostrimo come diagnosticare, pulire e ottimizzare il database WordPress in modo sicuro, con script pronti per la produzione.

Nella nostra esperienza di gestione di oltre 50 siti WordPress per clienti, il database medio accumula dal 50% all’80% di dati inutili dopo 2 anni di attività: revisioni di post, transienti scaduti, metadati orfani, commenti di spam. Un’ottimizzazione regolare puo ridurre le dimensioni del database del 30-50% e migliorare significativamente le performance delle query.

TL;DR — Checklist Rapida

  • Limita le revisioni dei post a 5 con define('WP_POST_REVISIONS', 5);
  • Pulisci i transienti scaduti con WP-CLI o query SQL mirate
  • Controlla l’autoload di wp_options: deve restare sotto 1MB
  • Rimuovi metadati orfani da wp_postmeta dopo la disinstallazione dei plugin
  • Esegui OPTIMIZE TABLE mensilmente su InnoDB
  • Aggiungi indici personalizzati su meta_key per i siti con ACF pesante
  • Automatizza tutto con uno script bash mensile via cron

Perché il Database WordPress Si Inglia

WordPress è progettato per accumulare dati. Ogni modifica a un post crea una revisione, ogni plugin salva opzioni in wp_options, ogni operazione di caching usa transienti. Il problema è che WordPress non pulisce automaticamente la maggior parte di questi dati:

Fonte di bloat Tabella Impatto Frequenza pulizia
Revisioni dei post wp_posts Raddoppia o triplica le dimensioni della tabella Mensile
Transienti scaduti wp_options La pagina più colpita: autoload rallenta ogni request Settimanale
Metadati orfani wp_postmeta Righe senza post correlato dopo eliminazione plugin Trimestrale
Commenti spam wp_comments Accumulano migliaia di righe su siti con blog attivo Settimanale
Log di plugin wp_options / custom tables Alcuni plugin salvano log senza limite di dimensione Mensile

Diagnosi: Come Valutare lo Stato del Database

Prima di intervenire, misura le dimensioni reali delle tabelle. Usa questo comando WP-CLI per ottenere un quadro completo:

wp db query "
SELECT 
  table_name AS 'Tabella',
  ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Dimensione MB',
  table_rows AS 'Righe'
FROM information_schema.TABLES 
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC;"

Per identificare l’autoload eccessivo in wp_options — il problema più critico per le performance — esegui:

wp db query "
SELECT 
  option_name,
  ROUND(LENGTH(option_value) / 1024, 2) AS 'KB'
FROM wp_options 
WHERE autoload = 'yes' 
ORDER BY LENGTH(option_value) DESC 
LIMIT 20;"

Nella nostra esperienza, un sito con più di 800KB di autoload in wp_options ha tempi di risposta del server superiori di 200-400ms rispetto allo stesso sito con un autoload pulito. Il limite consigliato è sotto 1MB total per l’autoload.

Pulizia Revisioni e Post Orfani

Le revisioni dei post sono la causa numero uno del database bloat. WordPress salva ogni modifica come un record completo in wp_posts. Su un sito con 100 pagine e 200 post, dopo 2 anni puoi facilmente accumulare 5.000+ revisioni.

Limitare le revisioni in wp-config.php

// wp-config.php — aggiungere prima di ABSPATH
define('WP_POST_REVISIONS', 5);
define('EMPTY_TRASH_DAYS', 7); // svuota il cestino dopo 7 giorni

Questo riduce le revisioni a un massimo di 5 per post. Su siti con contenuti che cambiano frequentemente, questo puo ridurre la tabella wp_posts del 60% o più.

Eliminare revisioni esistenti con WP-CLI

# Elimina tutte le revisioni
wp post delete $(wp post list --post_type=revision --format=ids) --force

# Oppure via SQL (più veloce su database grandi)
wp db query "
DELETE FROM wp_posts 
WHERE post_type = 'revision';

DELETE FROM wp_postmeta 
WHERE post_id NOT IN (SELECT ID FROM wp_posts);

DELETE FROM wp_term_relationships 
WHERE object_id NOT IN (SELECT ID FROM wp_posts);"
⚠️ Attenzione: Esegui sempre un backup del database prima di qualsiasi pulvia SQL. Usa la nostra guida al backup WordPress per configurare un backup automatizzato prima di procedere.

Transienti Scaduti: Il Killer Silenzioso

I transienti sono il meccanismo di caching built-in di WordPress. I plugin li usano per salvare risposte API, risultati di calcoli e dati temporanei. Il problema: WordPress non elimina automaticamente i transienti scaduti. Li rimuove solo quando qualcuno cerca di leggerli. Se un plugin viene disinstallato, i suoi transienti restano nel database per sempre.

Pulizia transienti scaduti

# Via WP-CLI (consigliato)
wp transient delete --expired

# Via SQL per transienti con prefisso _transient_timeout_
wp db query "
DELETE FROM wp_options 
WHERE option_name LIKE '\_transient\_%' 
AND option_name NOT LIKE '\_transient\_timeout\_%';"

Per siti multi-sito gestiti da agenzie, crea uno script che itera su tutti i siti:

#!/bin/bash
# clean-transients.sh — Pulizia transienti multi-sito
SITES=$(wp site list --field=domain --archived=false --deleted=false)

for SITE in $SITES; do
  echo "Pulizia transienti: $SITE"
  wp transient delete --expired --url=$SITE
  wp transient delete --all --url=$SITE 2>/dev/null
done
echo "Pulizia completata."

Autoload in wp_options: Il Problema Più Critico

La tabella wp_options contiene tutte le impostazioni di WordPress e dei plugin. Le righe con autoload = 'yes' vengono caricate in memoria su ogni singola richiesta. Quando i plugin accumulano opzioni in autoload, il server deve leggere e deserializzare megabyte di dati ad ogni page load.

Questo è il problema di performance più insidioso perché non genera errori visibili, ma aggiunge 100-500ms ad ogni richiesta.

Identificare e disattivare l’autoload non necessario

# Mostra le 20 opzioni autoload più pesanti
wp db query "
SELECT option_name, ROUND(LENGTH(option_value)/1024, 2) AS 'KB'
FROM wp_options 
WHERE autoload = 'yes' 
ORDER BY LENGTH(option_value) DESC 
LIMIT 20;"

# Disattiva l'autoload per opzioni sicure
wp db query "
UPDATE wp_options 
SET autoload = 'no' 
WHERE option_name IN (
  'widget_recent-posts',
  'widget_recent-comments',
  'rewrite_rules',
  'sidebars_widgets'
) AND autoload = 'yes';"
✅ Best practice: Dopo aver disattivato l’autoload, monitora il sito per 48 ore. Se tutto funziona, programma la pulizia mensile. Le opzioni di widget e sidebar possono essere caricate on-demand invece che ad ogni request.

Metadati Orfani in wp_postmeta

La tabella wp_postmeta cresce più di ogni altra. Ogni plugin che salva dati personalizzati — ACF, WooCommerce, Yoast SEO, Elementor — aggiunge righe qui. Quando un post viene eliminato, i suoi metadati non vengono sempre rimossi.

# Trova metadati orfani
wp db query "
SELECT COUNT(*) AS 'metadati orfani'
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;"

# Elimina metadati orfani
wp db query "
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;"

Per i siti che usano ACF con campi serializzati, controlla anche le chiavi meta non utilizzate:

# Trova le 20 chiavi meta più pesanti
wp db query "
SELECT meta_key, COUNT(*) AS 'conteggio', 
  ROUND(SUM(LENGTH(meta_value))/1024/1024, 2) AS 'MB totali'
FROM wp_postmeta 
GROUP BY meta_key 
ORDER BY SUM(LENGTH(meta_value)) DESC 
LIMIT 20;"

Indici Personalizzati per Performance Query

Se il tuo sito usa ACF con query su meta_key e meta_value, aggiungere un indice composito puo velocizzare le query del 90%:

# Aggiungi indice composito per query ACF frequenti
wp db query "
ALTER TABLE wp_postmeta 
ADD INDEX idx_meta_key_value (meta_key(50), meta_value(20));"

# Aggiungi indice su meta_value per campi numerici usati in ORDER BY
wp db query "
ALTER TABLE wp_postmeta 
ADD INDEX idx_meta_value_num (meta_key(50), meta_value(10));"

Verifica l’efficacia con EXPLAIN prima e dopo l’aggiunta dell’indice:

wp db query "EXPLAIN 
SELECT * FROM wp_postmeta 
WHERE meta_key = 'prezzo_prodotto' 
ORDER BY meta_value + 0 DESC 
LIMIT 20;"

OPTIMIZE TABLE e Manutenzione InnoDB

Dopo aver eliminato grandi quantità di dati, esegui OPTIMIZE TABLE per recuperare lo spazio fisico su disco. Su InnoDB, questo ricrea la tabella e deframmenta gli indici:

# Ottimizza tutte le tabelle di WordPress
wp db query "OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments;"

Nota: OPTIMIZE TABLE blocca la tabella durante l’operazione. Esegui fuori dagli orari di picco o usa pt-online-schema-change di Percona Toolkit per tabelle superiori a 1GB.

Script di Automazione Mensile

Per le agenzie che gestiscono multi-sito, l’ottimizzazione database deve essere automatizzata. Ecco uno script bash completo da eseguire via cron server:

#!/bin/bash
# wp-db-optimize.sh — Ottimizzazione database WordPress mensile
# Uso: 0 3 1 * * /opt/scripts/wp-db-optimize.sh /var/www/sito-cliente

WP_PATH=$1
BACKUP_DIR=/opt/backups/db
LOG_FILE=/var/log/wp-db-optimize.log
DATE=$(date +%Y%m%d-%H%M%S)

echo "[$DATE] Inizio ottimizzazione: $WP_PATH" >> $LOG_FILE

# 1. Backup prima di tutto
wp db export $BACKUP_DIR/db-$DATE.sql --path=$WP_PATH --allow-root 2>> $LOG_FILE

# 2. Pulisci revisioni (mantieni ultime 5)
wp post delete $(wp post list --post_type=revision --format=ids --path=$WP_PATH --allow-root) --force --path=$WP_PATH --allow-root 2>> $LOG_FILE

# 3. Pulisci transienti scaduti
wp transient delete --expired --path=$WP_PATH --allow-root 2>> $LOG_FILE

# 4. Elimina spam e commenti nel cestino
wp db query "DELETE FROM wp_comments WHERE comment_approved IN ('spam', 'trash');" --path=$WP_PATH --allow-root 2>> $LOG_FILE

# 5. Elimina metadati orfani
wp db query "DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id = p.ID WHERE p.ID IS NULL;" --path=$WP_PATH --allow-root 2>> $LOG_FILE

# 6. Ottimizza tabelle InnoDB
wp db query "OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments, wp_terms, wp_term_taxonomy;" --path=$WP_PATH --allow-root 2>> $LOG_FILE

echo "[$DATE] Ottimizzazione completata." >> $LOG_FILE

Programma lo script via crontab per il primo del mese alle 3:00 AM:

# Crontab — ottimizzazione database mensile
0 3 1 * * /opt/scripts/wp-db-optimize.sh /var/www/sito-cliente-1
30 3 1 * * /opt/scripts/wp-db-optimize.sh /var/www/sito-cliente-2

Strumenti per il Monitoraggio Database

Strumento Tipo Costo Quando usarlo
Query Monitor Plugin WordPress Gratis Diagnosi query lente in sviluppo
Percona Toolkit CLI server Gratis Analisi slow query log su database grandi
Adminer PHP singolo file Gratis Ispezione rapida database via browser
MySQL slow query log Config server Gratis Produzione, query superiori a 2 secondi
New Relic / Datadog SaaS APM $20-50/mese Monitoraggio continuo multi-sito

FAQ — Ottimizzazione Database WordPress

Con che frequenza devo ottimizzare il database WordPress?

Per siti attivi con pubblicazione frequente, l’ottimizzazione mensile è ideale. Per siti con traffico moderato, ogni 2-3 mesi è sufficiente. Il monitoraggio delle dimensioni di wp_options e wp_postmeta dovrebbe essere settimanale per i siti multi-sito gestiti da agenzie.

OPTIMIZE TABLE è sicuro per siti in produzione?

Su tabelle InnoDB inferiori a 1GB, OPTIMIZE TABLE è generalmente sicuro ma blocca la tabella durante l’operazione. Per tabelle più grandi, usa pt-online-schema-change di Percona Toolkit che opera senza lock. Esegui sempre fuori dagli orari di picco.

Quali plugin causano più bloat nel database?

I plugin che generano più bloat sono: page builder (Elementor, WPBakery) che salvano metadati serializzati per ogni pagina, plugin SEO che accumulano dati strutturati, plugin di caching che non puliscono i transienti, e plugin WooCommerce su store con molti prodotti e variazioni.

Come faccio a sapere se l’autoload di wp_options è troppo grande?

Esegui wp db query "SELECT SUM(LENGTH(option_value)) FROM wp_options WHERE autoload='yes';". Se il risultato supera 1MB (1.048.576 byte), devi pulire l’autoload. Sopra 2MB, il sito ha un problema di performance critico che aggiunge 200-500ms ad ogni richiesta.

Posso automatizzare la pulizia del database senza plugin?

Sì, usando WP-CLI combinato con cron di sistema. Lo script bash fornito in questa guida esegue backup, pulizia revisioni, eliminazione transienti, rimozione metadati orfani e ottimizzazione tabelle senza alcun plugin aggiuntivo. È la soluzione più efficiente per le agenzie che gestiscono multi-sito.

Gestisci i siti WordPress dei tuoi clienti?

AgencyPilot ti dà report AI, uptime monitoring, backup e portale clienti in un’unica dashboard. Gratis per 3 siti.

Prova gratis
Leggi anche
Tutti gli articoli
Tutti gli articoli