Performance Tuning¶
Guida all'ottimizzazione delle performance del database PostgreSQL per SGV GE.CO.
Tabelle ad Alto Volume¶
Le tabelle con il maggior numero di record richiedono attenzione speciale:
| Tabella | Righe (approx) | Colonne | Impatto |
|---|---|---|---|
vv_ottico |
2.027.685 | - | Documenti scansionati, I/O intensivo |
vv_figura |
653.644 | 32 | Soggetti del verbale, join frequenti |
vv_infrazione |
390.466 | 61 | Infrazioni, sempre in join con verbale |
vv_verbale |
390.143 | 71 | Tabella centrale, query piu frequenti |
vv_verba_veicolo |
384.085 | 40 | Associazione verbale-veicolo |
vv_dett_blocchetto |
344.380 | - | Dettagli blocchetti |
vv_notifica |
289.708 | 69 | Ciclo notifica, molte colonne |
vv_veicolo |
284.200 | - | Registry veicoli |
vv_preavviso |
273.519 | 40 | Preavvisi |
vv_pagamento |
259.964 | 43 | Pagamenti |
Paginazione Obbligatoria¶
Query su vv_verbale senza paginazione
Per comuni con oltre 100K verbali, una query senza LIMIT/OFFSET puo causare OutOfMemoryError o timeout. Usare sempre la paginazione nelle query JPA.
Pattern JPA consigliato¶
// Corretto: con paginazione
TypedQuery<VvVerbale> query = em.createQuery(
"SELECT v FROM VvVerbale v WHERE v.fStato = :stato", VvVerbale.class);
query.setParameter("stato", "A");
query.setFirstResult(offset); // Offset
query.setMaxResults(pageSize); // Limite (es: 50)
List<VvVerbale> results = query.getResultList();
// SBAGLIATO: carica tutti i record in memoria
List<VvVerbale> ALL = em.createQuery(
"SELECT v FROM VvVerbale v", VvVerbale.class)
.getResultList(); // OutOfMemoryError per grandi volumi
Ottimizzazioni per Query Frequenti¶
Ricerca verbali per codice¶
La colonna rg_codice_verbale e usata come chiave di ricerca principale dagli operatori. Verificare che esista un indice:
Ricerca per codice fiscale¶
Le ricerche per CF attraversano vv_anagrafica e vv_figura:
CREATE INDEX IF NOT EXISTS idx_vv_anagrafica_cf
ON own_c_a662.vv_anagrafica (cod_fiscale_p_iva);
CREATE INDEX IF NOT EXISTS idx_vv_figura_cf
ON own_c_a662.vv_figura (cod_fiscale_p_iva);
Ricerca per targa¶
Filtro per stato verbale¶
Le query piu comuni filtrano per f_stato, f_stato_pag, f_stato_notifica:
CREATE INDEX IF NOT EXISTS idx_vv_verbale_stati
ON own_c_a662.vv_verbale (f_stato, f_stato_pag, f_stato_notifica);
Operazioni Bulk¶
PDF Generation¶
La generazione massiva di PDF (notifiche, bollettini) e CPU-intensiva.
Usare Quartz per operazioni bulk
Non generare PDF in modo sincrono nelle chiamate REST. Utilizzare i job Quartz di ElaborazioneService per la generazione asincrona tramite lotti (vv_lotto).
Lotti di Lavorazione¶
Il sistema lavora per lotti (vv_lotto, 98K record). Le operazioni massive (produzione notifiche, trasmissione, ricezione esiti) vengono processate un lotto alla volta per evitare lock prolungati.
Data Warehouse¶
Alimentazione DWH¶
Le tabelle sa_* (staging area) vengono alimentate dalle tabelle operative vv_*. L'ETL trasforma i dati nelle dimensioni e fatti dwh_*.
Indici su staging area
Le tabelle sa_* nel DWH replicano grandi volumi (es: sa_vv_figura con 654K righe). Verificare gli indici sulle colonne di join usate dall'ETL.
Monitoring¶
Query utili per il monitoraggio¶
-- Tabelle piu grandi (spazio disco)
SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) as total_size
FROM pg_class WHERE relnamespace = 'own_c_a662'::regnamespace
ORDER BY pg_total_relation_size(oid) DESC LIMIT 20;
-- Indici non utilizzati
SELECT schemaname, relname, indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE schemaname = 'own_c_a662' AND idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;
-- Query lente (richiede pg_stat_statements)
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC LIMIT 10;
Connessioni¶
Pool di Connessioni¶
Le connessioni sono gestite da WildFly tramite JNDI datasource:
- Datasource:
java:jboss/PostgresDSPoolGenerale(DB generale) - Datasource:
java:jboss/PostgresDSPool(DB reparto) - Pool size: Configurato in WildFly
standalone.xml
Connection pool sizing
Per ambienti con molti utenti concorrenti, aumentare max-pool-size nel datasource WildFly. Valore consigliato: 20-50 connessioni per datasource.
MongoDB (OtticoService)¶
Non documentato
Il database MongoDB usato da OtticoService per l'elaborazione ottica delle immagini non e ancora accessibile per la documentazione. Assicurarsi che siano presenti indici su verbaleId e timestamp.