Database Optimization · 3 min read · Nov 11, 2025
Ottimizzare DSPAM + MySQL 4.1
Introduzione
DSPAM è un filtro antispam scalabile e open-source basato sui contenuti, progettato per sistemi aziendali multi-utente. È ottimo per filtrare lo spam, ma su server di posta molto occupati la potatura dei database MySQL richiede troppo tempo…
Lo script predefinito purge-4.1.sql fornito con DSPAM può essere notevolmente ottimizzato aggiungendo indici al database e utilizzando correttamente gli indici durante la potatura.
Iniziamo ad aggiungere alcuni indici alla tabella dspam_token_data. Aggiungere INDICI e utilizzare correttamente gli indici ci consente di interrogare i database in modo estremamente veloce.
Lo script e la struttura della tabella predefiniti forniti con DSPAM causano scansioni complete della tabella poiché i dati non sono indicizzati o gli indici non vengono utilizzati correttamente.
Aggiungere indici
Per iniziare, dobbiamo aggiungere alcuni indici alle tabelle. Gli indici ci consentono di interrogare i database molto più velocemente poiché non dobbiamo eseguire scansioni complete della tabella. (Il nostro attuale database DSPAM è di 8,5 GB e le scansioni complete della tabella portano letteralmente l’intero server di posta a un arresto.)
Collegati al server del database ed emetti i seguenti comandi:
mysql> alter table dspam_token_data add index(spam_hits);
mysql> alter table dspam_token_data add index(innocent_hits);
mysql> alter table dspam_token_data add index(last_hit);
Questo aggiungerà indici alle colonne spam_hits, innocent_hits e last_hit.
La tabella dspam_signature_data è già correttamente indicizzata - tuttavia, gli indici non vengono utilizzati correttamente durante la pulizia dei dati obsoleti (maggiore informazione su questo di seguito).
Le parti interessanti dello script fornito con DSPAM sono le seguenti:
delete from dspam_token_data
where (innocent_hits*2) + spam_hits < 5
and @a-to_days(last_hit) > 60;
Questa query non utilizza l’indice sulla colonna last_hit poiché chiamiamo la funzione to_days sul campo e perdiamo così la possibilità di utilizzare l’indice.
Nota anche che gli indici aggiunti su innocent_hits e spam_hits vengono utilizzati qui. Cambia la query in:
delete from dspam_token_data
where (innocent_hits*2) + spam_hits < 5
and from_days(@a-60) > last_hit;
Prossima query:
delete from dspam_token_data
where innocent_hits = 1 and spam_hits = 0
and @a-to_days(last_hit) > 15;
Stesso problema - cambia questo in:
delete from dspam_token_data
where innocent_hits = 1 and spam_hits = 0
and from_days(@a-15) > last_hit;
Prossima query:
delete from dspam_token_data
where innocent_hits = 0 and spam_hits = 1
and @a-to_days(last_hit) > 15;
Cambia questo in:
delete from dspam_token_data
where innocent_hits = 0 and spam_hits = 1
and from_days(@a-15) > last_hit;
Prossima query:
delete from dspam_token_data
USING
dspam_token_data LEFT JOIN dspam_preferences
ON dspam_token_data.uid = dspam_preferences.uid
AND dspam_preferences.preference = ‘trainingMode’
AND dspam_preferences.value in(‘TOE’,’TUM’,’NOTRAIN’)
WHERE @a-to_days(dspam_token_data.last_hit) > 90
AND dspam_preferences.uid IS NULL;
Cambia questo in:
delete from dspam_token_data
USING
dspam_token_data LEFT JOIN dspam_preferences
ON dspam_token_data.uid = dspam_preferences.uid
AND dspam_preferences.preference = ‘trainingMode’
AND dspam_preferences.value in(‘TOE’,’TUM’,’NOTRAIN’)
WHERE from_days(@a-90) > dspam_token_data.last_hit
AND dspam_preferences.uid IS NULL;
Prossima query:
delete from dspam_token_data
USING
dspam_token_data LEFT JOIN dspam_preferences
ON dspam_token_data.uid = dspam_preferences.uid
AND dspam_preferences.preference = ‘trainingMode’
AND dspam_preferences.value = ‘TUM’
WHERE @a-to_days(dspam_token_data.last_hit) > 90
AND innocent_hits + spam_hits < 50
AND dspam_preferences.uid IS NOT NULL;
Cambia questo in:
delete from dspam_token_data
USING
dspam_token_data LEFT JOIN dspam_preferences
ON dspam_token_data.uid = dspam_preferences.uid
AND dspam_preferences.preference = ‘trainingMode’
AND dspam_preferences.value = ‘TUM’
WHERE from_days(@a-90) > dspam_token_data.last_hit
AND innocent_hits + spam_hits < 50
AND dspam_preferences.uid IS NOT NULL;
E infine:
delete from dspam_signature_data
where @a-14 > to_days(created_on);
dovrebbe essere cambiato in:
delete from dspam_signature_data
where from_days(@a-14) > created_on;
Esecuzione di test con lo script di potatura modificato
Quindi, le modifiche aiutano? Sì! Di seguito sono riportati i tempi per lo script originale non modificato e lo script nuovo modificato:
real 2m57.726s
user 0m0.010s
sys 0m0.000s
E per il nuovo script modificato (utilizzato sullo stesso set di dati):
real 0m1.794s
user 0m0.000s
sys 0m0.000s
Lo script ha impiegato quasi 3 minuti utilizzando lo script predefinito di DSPAM e meno di 2 secondi utilizzando lo script e gli indici modificati.
Pro e contro
Quando aggiungi indici alle tabelle, utilizzi molto più spazio su disco per i tuoi dati. Se hai bisogno delle prestazioni durante la potatura dei dati e puoi permetterti di utilizzare lo spazio su disco extra, allora aggiungi gli indici e modifica il tuo script di potatura come spiegato sopra. Se hai solo una piccola quantità di dati nel tuo database e le prestazioni non sono un problema, allora rimani con lo script predefinito di DSPAM.
Link
- La homepage di DSPAM
Feedback
Tutti i feedback sono apprezzati - sentiti libero di contattarmi via email: laursen[at]netgroup.dk
Ricevi i nuovi post nella tua casella di posta.
Nessuno spam. Disiscriviti in qualsiasi momento.