¿Qué factor de relleno para la tabla de almacenamiento en caché?

10

He actualizado / accedido a la tabla donde almaceno objetos java serializados. Están en la tabla durante 2-3 horas (también se actualizan durante ese período) y luego se eliminan. El tamaño de la mesa es de alrededor de 300 MB. He visto que está muy, muy a menudo aspirado y me pregunto si cambiarlo fillfactorayudaría.

Michal
fuente

Respuestas:

17

Las palabras clave aquí son:

  1. "muy actualizado"
  2. "en la mesa durante 2-3 horas".

El punto 1. es una indicación de un factor de relleno más bajo, mientras que 2. es lo contrario. Ayuda al rendimiento si se almacenan varias versiones de fila en la misma página de datos. Las actualizaciones CALIENTES lograrían eso. Lee aquí o aquí . Necesitan algo de margen de maniobra en la página de datos, como tuplas muertas o espacio reservado por un fillfactor<100. Pero solo pueden hacer lo suyo, si ningún índice involucra alguna de las columnas actualizadas , lo que debería ser cierto para su caso.

Otro factor importante aquí sería el tamaño de la tupla (en comparación con el tamaño de su página (que generalmente es de 8 kb). Más detalles en esta respuesta relacionada:

Si el tamaño de la tupla es de 4 kb o más, reducir el factor de relleno sería inútil, ya que nunca puede haber más de una tupla en una página de datos. También podría dejarlo en 100(que es el valor predeterminado de todos modos). Sin embargo, algunos tipos de datos son "tostados" y almacenados fuera de línea si exceden un límite de tamaño, por lo que las tuplas que requieren tanto en la bifurcación de la relación principal son raras.

Hagas lo que hagas, VACUUM se ejecutará a menudo. Y eso es generalmente algo bueno, no me preocuparía por eso. Creas muchas tuplas muertas. VACUUMidentifica filas muertas que ya no son visibles para ninguna transacción abierta. El manual:

La forma estándar de VACUUMelimina las versiones de fila muerta en tablas e índices y marca el espacio disponible para la reutilización futura .

El énfasis audaz es mío.
Puede jugar con configuraciones por tabla para autovacuum para activarlo menos (o más) a menudo solo para esta tabla:

Se toman los umbrales predeterminados y los factores de escala postgresql.conf, pero es posible anularlos tabla por tabla ;

El énfasis audaz es mío. En particular con autovacuum_vacuum_thresholdyautovacuum_vacuum_scale_factor . Correr VACUUMmucho podría ser una buena idea, en lugar de una muy baja fillfacter. Eso depende de los patrones de acceso. Si todas las tuplas viven, digamos, 3 horas y cada una se actualiza varias veces, aún así bajaría fillfactora algo así como 50. Tendrás que probar y encontrar el punto óptimo.

Alternativas

Todo esto a un lado, ya que sus datos parecen ser volátiles para comenzar: use una UNLOGGEDtabla :

Los datos escritos en tablas no registradas no se escriben en el registro de escritura anticipada (consulte el Capítulo 29 ), lo que los hace considerablemente más rápidos que las tablas normales. Sin embargo, no son seguros : una tabla no registrada se trunca automáticamente después de un bloqueo o apagado no limpio. El contenido de una tabla no registrada tampoco se replica en servidores en espera.

El énfasis audaz es mío. No use esto si su servidor puede fallar y aún necesita los datos después. Pero si estamos hablando de datos de sesión para aplicaciones web, este podría ser un precio aceptable a pagar.

O, aún más radical: use una tienda de valores clave como Redis si puede prescindir de las características y la seguridad proporcionadas por un RDBMS por completo.

Erwin Brandstetter
fuente
Creo que DESBLOQUEADO es exactamente lo que necesito
Michal
0

Sugeriría un DBMS de valor clave, pero lo lanzo por el bien del interés.

En lugar de realizar sentencias INSERT & DELETE, solo haga UPDATE

La estructura de la tabla será algo así como

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

La columna de sujeción de objetos será de longitud fija para evitar divisiones y movimientos de fila. Cambie el tamaño de esta columna para acomodar sus objetos y llenar de manera eficiente una página en el disco.

Llene previamente su tabla con tantas filas como necesite y algunas más.

Cuando se va a escribir un objeto, busque una fila con Used = False y ACTUALICE esa fila. Cuando se va a destruir un objeto, configúrelo como "Falso". No se crea basura y, por lo tanto, no se recolecta basura.

Por supuesto, hay muchas, muchas condiciones de excepción para manejar (desbordamiento de fila, desbordamiento de tabla, condiciones de carrera en el uso de ID, etc.) pero ninguna es insuperable.

Michael Green
fuente
Por lo que yo entiendo, estas ACTUALIZACIONES generalmente todavía escriben una copia completamente nueva de la fila en el disco a menos que sea una actualización CALIENTE. Por lo tanto, aún terminará necesitando GC / Vacío con el tiempo.
Jeff Widman