2009-06-01 13 views
10

Ho una tabella DB con 25 milioni di righe, ~ 3K ciascuna (cioè ~ 75 GB), che insieme a più indici che uso (un ulteriore 15-20 GB) non sarà adatto interamente alla memoria (64 GB sulla macchina). Una query tipica individua 300 righe attraverso un indice, opzionalmente le filtra in ~ 50-300 righe usando altri indici, recuperando infine le righe corrispondenti. I tempi di risposta variano tra 20 ms su un DB caldo a 20 secondi su un DB freddo. Ho due domande correlate:Prestazioni di cache Postgresql (memoria) + Come riscaldare la cache

  1. in un dato momento come posso controllare quale parte (%) di tabelle e indici specifici viene memorizzata nella cache in memoria?

  2. Qual è il modo migliore per scaldare la cache prima di aprire il DB alle query? Per esempio. "select *" forza una scansione sequenziale (~ 15 minuti sul DB freddo) ma i tempi di risposta che seguono sono ancora scadenti. C'è un modo integrato per effettuare questa operazione invece che tramite query un

Grazie, si sente libero di rispondere anche per e-mail ([email protected]])

-? Shaul

risposta

1

Ad. 1 - Non ho assolutamente idea.

Ad. 2 - perché non scegli solo casualmente alcune query che sai essere importanti e le esegui sul server freddo? più le query verranno eseguite, migliore sarà il processo di riscaldamento.

2

2) Solitamente risolvo questo problema registrando le query da un sistema live e riproducendole. Questo riscalda le parti tipiche dei dati e non le parti che non sono usate frequentemente (che altrimenti perderebbero la RAM).

+0

Il problema è che non riesco a indovinare le query dell'utente, penso "Amazon" - quali saranno le prossime 10000 domande? Quindi mi sarebbe piaciuto eseguire qualcosa che estraesse tabelle e indici specifici nella cache. –

+0

Non indovinare. Effettua un log effettivo dagli ultimi 5 minuti o dalle ultime 10.000 query. Ho lavorato su "un fornitore leader di motori di ricerca" e questo funziona alla grande. Oppure, se si dispone di server in esecuzione e si desidera riscaldarne uno nuovo, è possibile eseguire il mirroring delle query sul server che deve essere sottoposto a riscaldamento. – Thomas

3

Per quanto riguarda il primo punto, il modulo contrib "pg_buffercache" consente di ispezionare il contenuto della cache del buffer. Mi piace definire questo:

create or replace view util.buffercache_hogs as 
select case 
     when pg_buffercache.reldatabase = 0 
      then '- global' 
     when pg_buffercache.reldatabase <> (select pg_database.oid from pg_database where pg_database.datname = current_database()) 
      then '- database ' || quote_literal(pg_database.datname) 
     when pg_namespace.nspname = 'pg_catalog' 
      then '- system catalogues' 
     when pg_class.oid is null and pg_buffercache.relfilenode > 0 
      then '- unknown file ' || pg_buffercache.relfilenode 
     when pg_namespace.nspname = 'pg_toast' and pg_class.relname ~ '^pg_toast_[0-9]+$' 
      then (substring(pg_class.relname, 10)::oid)::regclass || ' TOAST'::text 
     when pg_namespace.nspname = 'pg_toast' and pg_class.relname ~ '^pg_toast_[0-9]+_index$' 
      then ((rtrim(substring(pg_class.relname, 10), '_index'))::oid)::regclass || ' TOAST index' 
     else pg_class.oid::regclass::text 
     end as key, 
     count(*) as buffers, sum(case when pg_buffercache.isdirty then 1 else 0 end) as dirty_buffers, 
     round(count(*)/(SELECT pg_settings.setting FROM pg_settings WHERE pg_settings.name = 'shared_buffers')::numeric, 4) as hog_factor 
from pg_buffercache 
    left join pg_database on pg_database.oid = pg_buffercache.reldatabase 
    left join pg_class on pg_class.relfilenode = pg_buffercache.relfilenode 
    left join pg_namespace on pg_namespace.oid = pg_class.relnamespace 
group by 1 
order by 2 desc; 

Inoltre, il modulo contrib "pageinspect" permette di accedere una pagina specifica da una relazione, quindi suppongo che si può semplicemente scorrere tutte le pagine di un rapporto di loro afferra?

select count(get_raw_page('information_schema.sql_features', n)) 
from generate_series(0, 
     (select relpages-1 from pg_class where relname = 'sql_features')) n; 

Questo caricherà tutto information_schema.sql_features nella cache.

0

Non provare a riscaldare la memoria, questo è il postgresql e il sistema operativo. Basta dividere le tabelle (e gli indici) nelle partizioni e provare a lavorare con i set di dati più piccoli. Se riesci a stabilire un buon piano di partizionamento, allora non ci sono problemi con enormi indici o tabelle. Se vuoi ancora scaldare tabelle e indici, allora può essere memorizzato nella cache completamente nella RAM perché è più piccolo di prima.

+0

Penso che il riscaldamento e il partizionamento della cache siano due problemi distinti. Il partizionamento non risolve il problema iniziale di "cold cache". È un problema di I/O. – Jan

Problemi correlati