Vai al contenuto

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:

CREATE INDEX IF NOT EXISTS idx_vv_verbale_rg_codice
ON own_c_a662.vv_verbale (rg_codice_verbale);

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

CREATE INDEX IF NOT EXISTS idx_vv_veicolo_targa
ON own_c_a662.vv_veicolo (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.