Risoluzione dei problemi relativi alle prestazioni
Utilizza le seguenti indicazioni per risolvere i problemi relativi IBM Cloud® Databases for PostgreSQL alle prestazioni.
Per una panoramica generale, consultare la sezione PostgreSQL prestazioni.
Prestazioni lente del database
I sintomi tipici di questo problema sono i seguenti:
- Elevato utilizzo della memoria o delle operazioni di I/O (input/output) del disco
- Query lente
La causa più comune è l'esame delle query lente. Per verificare se questo è il caso, procedere come segue:
-
Elenca le query di lunga durata:
select age(now(),query_start), pid, client_addr, state, substring(query,0,80) from pg_stat_activity where state != 'idle' order by 1 desc; -
Convalida blocco query:
select pg_blocking_pids(pid), pid AS blocked_pid, state, query, age(now(),query_start) AS duration from pg_stat_activity where array_length(pg_blocking_pids(pid),1) > 0 order by 1,2; -
Controlla il piano di esecuzione della query:
Explain <query>; -
Verificare se mancano statistiche del database. Utilizzare la seguente query per la convalida: Azione > Esegui analisi In alternativa, eseguire il seguente comando:
Analyze <tablename> select relname, n_live_tup, n_dead_tup, last_vacuum,last_autovacuum,last_analyze,last_autoanalyze, analyze_count,autoanalyze_count from pg_stat_all_tables where schemaname='public'; -
Controllare se l'indice è assente dalla tabella. PostgreSQL fornisce metodi di indicizzazione quali B-Tree, hash, GiST,SP-GiST, GIN e BRIN. Utilizza uno di questi metodi per creare l'indice.
-
Controlla se la tabella è gonfia. Esegui la seguente query per verificare. Azione > Esegui aspirapolvere
In alternativa, utilizzare la seguente istruzione:
SELECT relname AS table_name, pg_size_pretty(pg_relation_size(c.oid)) AS actual_size, pg_size_pretty( CASE WHEN c.relpages = 0 THEN 0 ELSE (pg_relation_size(c.oid) - (c.relpages * (current_setting('block_size')::numeric - 24))) * 100 / pg_relation_size(c.oid) END ) AS bloat_percentage, pg_size_pretty( CASE WHEN c.relpages = 0 THEN 0 ELSE (pg_relation_size(c.oid) - (c.relpages * (current_setting('block_size')::numeric - 24))) END )AS bloat_size FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE relkind = 'r' AND n.nspname = 'public' -- Adjust schema if needed ORDER BY bloat_size DESC NULLS LAST; -
Verificare se il database o gli oggetti sono stati creati con
pg_dumpopg_restore. Utilizza Azione > Aggiorna statistiche per aggiornare. -
Assicurarsi che sia allocato
work_memspazio sufficiente, se la query sta completando un'operazione di ordinamento. -
Utilizza
pg_statle istruzioni per ottenere le seguenti informazioni:-
query tempo medio di esecuzione e numero di chiamate
-
Percentuale di utilizzo della CPU da parte delle query
-
percentuale di utilizzo della memoria da parte delle query
-
pg_stat_activity, pg_stat_bgwriter, e pg_buffercache sono strumenti importanti in PostgreSQL per monitorare e comprendere le prestazioni del database.
Monitoraggio dell'implementazione e monitoraggio del carico del database
Databases for PostgreSQL Le distribuzioni offrono un'integrazione con il IBM Cloud Monitoring servizio per il monitoraggio dell'utilizzo delle risorse nella tua distribuzione. Utilizza questo servizio per monitorare la tua distribuzione (disco e memoria) e il carico del tuo database.
Utilizza Cloud Databases i dashboard per impostare avvisi sulle soglie relative a CPU, memoria e IOPS del disco. Molte delle metriche disponibili, come l'utilizzo del disco e gli IOPS, sono utili per aiutarti a configurare il ridimensionamento automatico nella tua distribuzione. Il ridimensionamento automatico non è abilitato per impostazione predefinita, pertanto è necessario configurarlo manualmente.
Osservare le tendenze di utilizzo e configurare il ridimensionamento automatico in modo da rispondere a tali tendenze può aiutare ad alleviare i problemi di prestazioni prima che i database diventino instabili a causa dell'esaurimento delle risorse. Ad esempio, modifiche nell'I/O del disco o errori della CPU o della memoria che causano problemi di prestazioni.
IOPS disco
Il numero di operazioni di input/output al secondo (IOPS) è limitato dal tipo e dalle dimensioni del volume di archiviazione. I volumi di archiviazione per Databases for PostgreSQL le distribuzioni sono forniti su volumi Block Storage Endurance nel livello da 10 IOPS per GB.
Se il carico operativo raggiunge o supera il limite IOPS, le richieste e le operazioni del database vengono ritardate fino a quando il sottosistema di archiviazione non riesce a recuperare il ritardo. Periodi prolungati di carico elevato possono impedire alla tua distribuzione di elaborare le query e renderla effettivamente non disponibile. È possibile aumentare il numero di IOPS disponibili per la propria distribuzione aumentando le dimensioni del disco. Ad esempio, per 10 IOPS per livello GB, è possibile aumentare gli IOPS aumentando la dimensione del volume.
Periodi prolungati di utilizzo del disco anche solo del 40-50% possono avere un impatto negativo significativo sulle prestazioni del database. Assegnare almeno 100 GB di disco (1.000 IOPS) per gli ambienti di produzione. IOPS = 10 × GB allocati (ad esempio, 100 GB = 1.000 IOPS)
Utilizzo della memoria
La memoria è il modo più veloce ed efficiente per accedere ed elaborare i dati. Per questo motivo, un database funziona quasi sempre più velocemente utilizzando la memoria invece di leggere i dati dal disco. Ci sono altri parametri da considerare, come i cache hit, i blocchi letti e i blocchi colpiti. Il solo fatto di vedere un utilizzo della memoria al 100% non è di per sé motivo di preoccupazione. Se la memoria è esaurita e vengono utilizzate pagine di swap, le prestazioni possono diminuire in modo significativo.
È possibile impostare la quantità di memoria dedicata al pool di buffer condiviso del database regolando shared_buffers nella Databases for PostgreSQL configurazione. Il valore massimo consigliato è pari al 25% della memoria totale dell'implementazione. Assegnare troppa memoria al pool di buffer condiviso può privare il sistema della memoria necessaria per altri scopi, ostacolare le prestazioni o addirittura disabilitare il database.
Monitoraggio del carico del database
Hai due opzioni per controllare il carico del database:
Opzione 1. Verificare la presenza di query di lunga durata utilizzando IBM Cloud Logs ( ICL ):
Per ulteriori informazioni, consulta Come posso tenere traccia della cronologia delle query?
È possibile utilizzare la seguente query di DataPrime esempio in IBM Cloud Logs.
- Dopo il IBM Cloud caricamento dei log, passare alla </>DataPrime scheda. Non modificare nulla nella barra di ricerca </>Lucene.
- Dalla scheda </>DataPrime, esegui la seguente ricerca per trovare SQL in esecuzione da più di 1000 millisecondi. Puoi anche incollarlo nella ricerca della scheda </>DataPrime.
{
source logs|filter message.attr.durationMillis>=1000
}
Opzione 2. Abilita il log_min_duration_statement
L'uso di log_min_duration_statement specifica che vengono registrate le istruzioni che richiedono più tempo del numero di millisecondi specificato. Per ulteriori informazioni, vedere log_min_duration_statement.
È anche possibile installare l 'estensione pg_stat_statements:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
Questa estensione consente di interrogare le statistiche per trovare esempi di query particolarmente lunghe. È quindi possibile isolare i problemi e prendere in considerazione un modello di query diverso, indici nuovi o modificati, un design diverso delle tabelle o altre strategie per migliorare le prestazioni.
Query 1: Identificare le query che richiedono molto tempo
È possibile individuare le query che richiedono molto tempo eseguendo la seguente istruzione:
SELECT username, database, queryid, query_preview, calls, total_exec_time, pct_exec_time, ROUND(SUM(pct_exec_time) OVER (ORDER BY total_exec_time DESC)) AS cum_pct_exec_time, avg_exec_time FROM ( SELECT pu.usename AS username, pd.datname AS database, pss.queryid, LEFT(pss.query, 50) AS query_preview, pss.calls, ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time, ROUND((100.0 * pss.total_exec_time / SUM(pss.total_exec_time) OVER ())::numeric, 2) AS pct_exec_time, ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time FROM pg_stat_statements pss JOIN pg_user pu ON pss.userid = pu.usesysid JOIN pg_database pd ON pss.dbid = pd.oid ) AS subquery ORDER BY total_exec_time DESC LIMIT 25;
Questa istruzione produce il seguente risultato:
| username | Database | queryid | query_preview | chiamate | tempo_totale_di_esecuzione | tempo_di_esecuzione | cum_pct_tempo_di_esecuzione | tempo_di_esecuzione_medio |
|---|---|---|---|---|---|---|---|---|
| IBM | Postgres |
|
50685 | 38286.580 | 19.52 | 20 | 0.755 | |
| ibm | Postgres |
|
280111 | 28477.951 | 14.52 | 34 | 0.102 | |
| ibm | Postgres |
|
18 | 14568.978 | 7.43 | 41 | 809.388 | |
| ibm | Postgres |
|
18 | 12103.904 | 6.17 | 48 | 672.439 | |
| ibm | ibmclouddb |
|
37552 | 7799.984 | 3.98 | 52 | 0.208 | |
| (5 righe) |
La query tiene traccia delle statistiche di esecuzione delle istruzioni SQL e fornisce le seguenti informazioni:
- Mostra le 25 query che hanno richiesto più tempo in totale per essere eseguite
- Mostra chi ha eseguito la query, su quale database e un'anteprima della query
- Mostra la frequenza con cui è stata eseguita ciascuna query e il tempo medio impiegato
- Calcola la percentuale del tempo totale del database utilizzato da ciascuna query
- Fornisce un totale progressivo del tempo di utilizzo del database
Query 2: Identificare le query eseguite frequentemente
È possibile individuare le query eseguite frequentemente eseguendo la seguente istruzione:
SELECT
username,
database,
queryid,
query_preview,
calls,
pct_calls,
ROUND(SUM(pct_calls) OVER (ORDER BY calls DESC)) AS cum_pct_calls,
total_exec_time,
avg_exec_time
FROM (
SELECT
pu.usename AS username,
pd.datname AS database,
pss.queryid,
LEFT(pss.query, 50) AS query_preview,
pss.calls,
ROUND(100.0 * pss.calls / SUM(pss.calls) OVER (), 2) AS pct_calls,
ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time,
ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time
FROM
pg_stat_statements pss
JOIN pg_user pu ON pss.userid = pu.usesysid
JOIN pg_database pd ON pss.dbid = pd.oid
) AS subquery
ORDER BY
calls DESC
LIMIT 25;
Questa istruzione produce il seguente risultato:
| username | Database | queryid | query_preview | chiamate | pct_chiamate | cum_pct_chiamate | tempo_totale_di_esecuzione | tempo_di_esecuzione_medio |
|---|---|---|---|---|---|---|---|---|
| IBM | Postgres |
|
80285 | 23.84 | 24 | 16095.420 | 0.200 | |
| IBM | Postgres |
|
36832 | 10.94 | 35 | 548.787 | 0.015 | |
| IBM | Postgres |
|
20626 | 6.12 | 41 | 741.755 | 0.036 | |
| IBM | Postgres |
|
14702 | 4.36 | 45 | 23982.252 | 1.631 | |
| IBM | Postgres |
|
12436 | 3.69 | 49 | 1750.426 | 0.141 |
La query fornisce le seguenti informazioni:
- Mostra le 25 query eseguite più spesso
- Mostra chi ha eseguito la query, su quale database e un'anteprima della query
- Mostra quante volte è stata eseguita ciascuna query e quanto tempo ha richiesto in totale e in media
- Calcola la percentuale di tutte le chiamate di query rappresentate da ciascuna query
- Fornisce un totale progressivo delle chiamate di query
Ottieni le prestazioni attuali di tutte le query
-
Per ottenere le prestazioni attuali di tutte le query, eseguire la seguente istruzione:
select now() as t1,sum(total_exec_time) as et1, sum(calls) as c1 from pg_stat_statementsQuesto produce il seguente risultato:
Risultato dell'esecuzione di tutte le istruzioni di query correnti t1 et1 c1 30/09/2025 08:15:43.898157 +00 104109.55454499979 336889 (1 row) -
Quindi attendere 10 secondi ed eseguire la seguente istruzione:
select now() as t2,sum(total_exec_time) as et2, sum(calls) as c2 from pg_stat_statementsQuesto produce il seguente risultato:
Risultato dell'istruzione select now() t2 et2 c2 30/09/2025 08:16:18.943609 +00 104113.70054399982 336896 (1 row) -
Calcola le query al secondo:
Queries per second = (c2-c1)/(t2-t1) and average query performance = (et2-et1)/(c2-c1)
Le 10 query che richiedono più tempo
Per ottenere le 10 query che richiedono più tempo:
SELECT query, calls, total_exec_time/calls as avg_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
Questo produce il seguente risultato:
| Query | chiamate | tempo_medio | | | -------------- | -------------- | -------------- | | <privilegio insufficiente> | 14706 | 1.6311896077791408 | | <privilegio insufficiente> | 80305 | 0.2004813740987463 | | <privilegio insufficiente> | 6 | 800.7297508333332 | | <privilegio insufficiente> | 6 | 721.1415835000001 | | <privilegio insufficiente> | 10316 | 0.3907427791779766 | | <privilegio insufficiente> | 10316 | 0.35429842613416024 | | <privilegio insufficiente> | 10316 | 0.3184477990500202 | | <privilegio insufficiente> | 10316 | 0.2285179489143081 | | <privilegio insufficiente> | 12439 | 0.1407493980223488 | | <privilegio insufficiente> | 10316 | 0.1605010507948812 | | (10 righe) | | |
Ulteriori azioni che puoi intraprendere per migliorare le prestazioni
È inoltre possibile prendere in considerazione le seguenti azioni per risolvere i problemi relativi alle prestazioni:
-
Ottimizza le query lente
- Esegui EXPLAIN (ANALYZE, BUFFERS) sulle query lente. Questo mostra come il database esegue la query e dove è lento. Ad esempio:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM student WHERE student_id = 12345;-
Cerca:
-
Query che utilizzano molta memoria o spazio su disco
-
Aggiungi IBM Cloud risorse secondo necessità
-
Scala il disco/la memoria per ottenere IOPS e memoria più elevate
-
-
Gli indici mancanti o inefficienti sono una causa comune di query lente. Utilizza EXPLAIN per identificare le scansioni sequenziali e valuta l'aggiunta di indici.
-
Esegui VACUUM per facilitare l'analisi dello stato di salute del database.
-
Considerare l'utilizzo del pooling delle connessioni per gestire un numero maggiore di connessioni. Databases for PostgreSQL imposta il numero massimo di connessioni al Databases for PostgreSQL database a 115. 15 connessioni sono riservate al superutente per mantenere lo stato e l'integrità del database, mentre 100 connessioni sono disponibili per l'utente e le sue applicazioni. Una volta raggiunto il limite di connessioni, qualsiasi tentativo di avviare una nuova connessione genera un errore. Per evitare di sovraccaricare la distribuzione con connessioni, utilizzare il pooling delle connessioni oppure scalare la distribuzione e aumentare il limite di connessioni. Per ulteriori informazioni, vedere Gestione del PostgreSQL pooling delle connessioni.
-
Verificare la presenza di eventuali procedure di backup e caricamento batch dei dati, ad esempio: I backup automatici vengono eseguiti quotidianamente e conservati con un semplice programma di conservazione di 30 giorni. Se un backup è bloccato, è possibile controllare la sezione Backup disponibili e identificare il backup bloccato nella pagina dell'interfaccia utente cloud dell'istanza del database.
-
Controlla le tue IBM Cloud notifiche per eventuali interventi di manutenzione. Ad esempio, l'applicazione di patch al database.
-
Se ritieni che si tratti di un problema della piattaforma, ad esempio di manutenzione, contatta IBM l'assistenza con il CRN del database.