2012-08-27 9 views
18

Tengo una tabla con 7 columnas y 5 de ellas serán nulas. Tendré columnas nulas en int, text, date, boolean y money tipos de datos. Esta tabla contendrá millones de filas con muchos nulos. Me temo que los valores nulos ocuparán espacio.¿Las columnas anulables ocupan espacio adicional en PostgreSQL?

Además, ¿sabe si Postgres indexa valores nulos? Me gustaría evitar que indexe nulos.

Respuesta

34

Básicamente, los valores NULL ocupan 1 bit en el mapa de bits NULO. Pero no es tan simple como eso.

null mapa de bits (por fila) solo está allí si al menos una columna en esa fila tiene un valor de NULL. Esto puede llevar a un efecto paradox en tablas con 9 o más columnas: la asignación del primer valor NULL a una columna puede ocupar más espacio en el disco que escribirle un valor. Por el contrario, con la última columna que no sea nula, el mapa de bits nulo se descarta para la fila.

Físicamente, el mapa de bits inicial nula ocupa 1 byte entre las HeapTupleHeader (23 bytes) y los datos de las columnas reales o la fila OID (si todavía debe utilizar eso) - el cual siempre inicio a un múltiplo de MAXALIGN (típicamente 8 bytes). Esto deja 1 byte de relleno que es utilizado por el mapa de bits nulo inicial.

En efecto El almacenamiento NULL es totalmente gratuito para tablas de 8 columnas o menos.
Después de eso, se asignan otros MAXALIGN bytes (generalmente 8) para las siguientes columnas MAXALIGN * 8 (normalmente 64). Etc.

Más detalles in the manual y bajo estas preguntas relacionadas:

Una vez que entienda el relleno alineación de los tipos de datos, se puede optimizar aún más el almacenamiento :

Pero los casos son raros donde se puede ahorrar cantidades considerables de espacio. Normalmente no vale la pena el esfuerzo.

@Daniel ya cubre los efectos en el tamaño del índice.

+0

"El almacenamiento NULL es totalmente gratuito para tablas de 8 columnas o menos". - ¿Qué pasa si solo 1 columna contiene nulo? esto significa que el mapa de bits nulo con 1 byte se creará solo para mantener 1 bit? – Dejell

+0

El mapa de bits nulo está allí si hay valores nulos, con suficientes bytes para cubrir todas las columnas, más relleno al siguiente múltiplo de 'MAXALIGN'. –

+0

Gracias Erwin. Todavía no estoy seguro, ¿y si no tengo ningún valor nulo? ¿Todavía estaría allí? (tabla de muchos a muchos) – Dejell

11

Si los valores NULL llegan al índice o no dependen al menos del tipo del índice. Básicamente, esto sería para btree y gist tipos de índices, NO para hash, y parece SÍ o NO para gin tipos de índices en función de la versión de PostgreSQL.

Solía ​​haber una columna booleana amindexnulls en la tabla pg_catalog.pg_am que contenía esa información, pero no está en 9.1. Probablemente porque los índices se han vuelto aún más sofisticados entre las mejoras PG.

En el caso específico de sus datos, la mejor manera de saber sería medir la diferencia de tamaño de los índices, utilizando la función pg_relation_size('index_name'), entre los contenidos completamente NULOS y completamente NO NULOS, con su versión PG exacta, tipo de datos exacto, tipo de índice exacto y definición. Y sepa que posiblemente, un cambio futuro en cualquiera de estos parámetros puede cambiar el resultado.

Pero en cualquier caso, si "sólo" quiere evitar los nulos de indexación, que siempre es posible crear un índice parcial:

CREATE INDEX partial_idx(col) ON table WHERE (col is not null) 

Esto va a tomar menos espacio, pero si esto se va a la ayuda o no con la realización de consultas depende de estas consultas.

+7

+1 perspicaz. Con los índices parciales, es importante tener en cuenta que solo pueden ser utilizados por el planificador de consultas si puede verificar que la condición esté cubierta en la consulta. El planificador de consultas es inteligente, pero no puede resolver la lógica compleja a este respecto. Haga coincidir la cláusula 'WHERE' más o menos al pie de la letra para asegurarse de que el índice se pueda usar (posible' AND'-ed con más condiciones). [Detalles en el manual] (http://www.postgresql.org/docs/current/interactive/indexes-partial.html). –

+0

Cool .. Gracias por su respuesta – Luke101

Cuestiones relacionadas