Quale fattore di riempimento per la tabella di memorizzazione nella cache?


10

Ho una tabella fortemente aggiornata / accessibile in cui conservo oggetti java serializzati. Sono nella tabella per 2-3 ore (anche in quel periodo vengono aggiornati) e quindi rimossi. La dimensione della tabella è di circa 300 MB. Ho notato che è molto, molto spesso SOTTOVUOTO e mi chiedo se la modifica del fillfactorsarebbe utile?

Risposte:


17

Le parole chiave qui sono:

  1. "fortemente aggiornato"
  2. "nella tabella per 2-3 ore".

Il punto 1. indica un fattore di riempimento inferiore, mentre 2. è l'opposto. Aiuta le prestazioni se più versioni di riga sono memorizzate nella stessa pagina di dati. Gli aggiornamenti HOT lo raggiungerebbero. Leggi qui o qui . Hanno bisogno di un po 'di spazio sulla pagina dei dati - come tuple morte o spazio riservato da un fillfactor<100. Ma possono fare solo le loro cose, se nessun indice coinvolge una delle colonne aggiornate , il che dovrebbe essere vero per il tuo caso.

Un altro fattore importante qui sarebbe la dimensione della tupla (rispetto alla dimensione della tua pagina (che è più comunemente 8 kb). Maggiori dettagli in questa risposta correlata:

Se la dimensione della tupla è di 4 kb o più, ridurre il fattore di riempimento sarebbe inutile, dal momento che non ci può mai essere più di una tupla in una pagina di dati. Potresti anche lasciarlo a 100(che è comunque il default). Tuttavia, alcuni tipi di dati vengono "tostati" e archiviati fuori linea se superano un limite di dimensioni, pertanto le tuple che richiedono molto nella fork della relazione principale sono rare.

Qualunque cosa tu faccia, VACUUM verrà eseguita spesso. E questa è generalmente una buona cosa, non me ne preoccuperei. Crei molte tuple morte. VACUUMidentifica le righe morte che non sono più visibili a nessuna transazione aperta. Il manuale:

La forma standard VACUUMrimuove le versioni delle righe morte nelle tabelle e negli indici e indica lo spazio disponibile per il riutilizzo futuro .

Enorme enfasi sulla mia.
Puoi giocare con le impostazioni per tavolo per l'autovacuum per attivarlo meno (o più) spesso solo per questo tavolo:

Vengono prese le soglie e i fattori di scala predefiniti postgresql.conf, ma è possibile sovrascriverli tabella per tabella ;

Enorme enfasi sulla mia. In particolare con autovacuum_vacuum_thresholdeautovacuum_vacuum_scale_factor . Correre VACUUMmolto potrebbe essere una buona idea, anziché molto basso fillfacter. Dipende dai modelli di accesso. Se tutte le tuple vivono, diciamo, 3 ore e ognuna viene aggiornata più volte, abbasserei comunque fillfactora qualcosa come 50. Dovrai testare e trovare il punto giusto.

alternative

Tutto questo a parte, poiché i tuoi dati sembrano essere volatili per cominciare: usa una UNLOGGEDtabella :

I dati scritti su tabelle non blog non vengono scritti nel registro write-ahead (vedere il capitolo 29 ), il che li rende notevolmente più veloci delle tabelle ordinarie. Tuttavia, non sono a prova di crash : una tabella non bloccata viene automaticamente troncata dopo un arresto anomalo o un arresto impuro. Inoltre, i contenuti di una tabella non blog non vengono replicati nei server di standby.

Enorme enfasi sulla mia. Non utilizzarlo se il tuo server potrebbe andare in crash e hai ancora bisogno dei dati in seguito. Ma se stiamo parlando di dati di sessione per applicazioni Web, questo potrebbe essere un prezzo accettabile da pagare.

O ancora più radicale: usa un archivio di valori-chiave come Redis se puoi fare a meno delle funzionalità e della sicurezza fornite da un RDBMS.


Penso che UNLOGGED sia esattamente ciò di cui ho bisogno
Michal

0

Suggerirei un DBMS di valore-chiave, ma lo butto lì per motivi di interesse.

Invece di eseguire le istruzioni INSERT & DELETE, eseguire solo AGGIORNAMENTI.

La struttura della tabella sarà simile

ID      integer  -- sequential ID
Used    boolean  -- default FALSE
Object  -- whatever type is appropriate

La colonna contenente gli oggetti avrà una lunghezza fissa per evitare divisioni e spostamenti di righe. Ridimensiona questa colonna per accogliere i tuoi oggetti e riempire in modo efficiente una pagina sul disco.

Pre-riempire la tabella con tutte le righe necessarie e alcune altre.

Quando un oggetto deve essere scritto, trova una riga con Usato = Falso e AGGIORNA quella riga. Quando un oggetto deve essere distrutto, impostalo come "Falso". Non è stata creata la spazzatura e quindi non c'è la raccolta dei rifiuti.

Naturalmente ci sono molte, molte condizioni di eccezione da gestire (overflow delle righe, overflow della tabella, condizioni di competizione sull'utilizzo dell'ID ecc.) Ma nessuna è insormontabile.


Per quanto ho capito, questi AGGIORNAMENTI in genere scrivono ancora una copia completamente nuova della riga su disco a meno che non sia un aggiornamento CALDO. Quindi finisci per avere bisogno nel tempo di GC / Aspirazione.
Jeff Widman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.