Pregunta bastante simple, probablemente respondida en alguna parte, pero parece que no puedo formar la pregunta de búsqueda correcta para Google ...
¿El número de columnas en una tabla en particular afecta el rendimiento de una consulta, cuando se consulta en un subconjunto de esa tabla?
Por ejemplo, si la tabla Foo tiene 20 columnas, pero mi consulta solo selecciona 5 de esas columnas, ¿tener 20 (en lugar de, por ejemplo, 10) columnas afecta el rendimiento de la consulta? Suponga por simplicidad que cualquier cosa en la cláusula WHERE está incluida en esas 5 columnas.
Me preocupa el uso de la memoria caché del búfer de Postgres además de la memoria caché del disco del sistema operativo. Tengo muy poca comprensión del diseño de almacenamiento físico de Postgres. Las tablas se almacenan en varias páginas (el tamaño predeterminado es de 8k por página), pero no entiendo cómo se organizan las tuplas desde allí. ¿PG es lo suficientemente inteligente como para obtener solo del disco los datos que comprenden esas 5 columnas?
fuente
Respuestas:
El almacenamiento físico para las filas se describe en los documentos en Diseño de página de base de datos . El contenido de la columna para la misma fila se almacena en la misma página del disco, con la notable excepción de los contenidos editados de TOAST (demasiado grandes para caber en una página). El contenido se extrae secuencialmente dentro de cada fila, como se explica:
En el caso más simple (sin columnas TOAST), postgres buscará toda la fila, incluso si se necesitan pocas columnas. Entonces, en este caso, la respuesta es sí, tener más columnas puede tener un claro impacto adverso en la memoria caché del búfer de desperdicio, particularmente si el contenido de la columna es grande mientras aún está por debajo del umbral de TOAST.
Ahora el caso de TOAST: cuando un campo individual excede ~ 2kB, el motor almacena el contenido del campo en una tabla física separada. También entra en juego cuando la fila completa no cabe en una página (8kB por defecto): algunos de los campos se mueven al almacenamiento de TOAST. Doc dice:
Los contenidos de TOAST no se obtienen cuando no se necesitan explícitamente, por lo que su efecto en el número total de páginas que se debe recuperar es pequeño (unos pocos bytes por columna). Esto explica los resultados en la respuesta de @ dezso.
En cuanto a las escrituras, cada fila con todas sus columnas se reescribe por completo en cada ACTUALIZACIÓN, sin importar qué columnas se cambien. Entonces, tener más columnas es obviamente más costoso para las escrituras.
fuente
La respuesta de Daniel se centra en el costo de leer filas individuales. En este contexto: poner
NOT NULL
columnas de tamaño fijo primero en su tabla ayuda un poco. Poner las columnas relevantes primero (las que buscas) ayuda un poco. Minimizar el relleno (debido a la alineación de datos) al jugar tetris de alineación con sus columnas puede ayudar un poco. Pero el efecto más importante aún no se ha mencionado, especialmente para tablas grandes.Obviamente, las columnas adicionales hacen que una fila cubra más espacio en el disco, por lo que caben menos filas en una página de datos (8 kB por defecto). Las filas individuales se extienden por más páginas. El motor de la base de datos generalmente tiene que buscar páginas enteras, no filas individuales . Poco importa si las filas individuales son algo más pequeñas o más grandes, siempre y cuando haya que leer el mismo número de páginas.
Si una consulta obtiene una porción (relativamente) pequeña de una tabla grande, donde las filas se extienden más o menos al azar en toda la tabla, con el apoyo de un índice, esto dará como resultado aproximadamente el mismo número de lecturas de página, con poca consideración a tamaño de fila. Las columnas irrelevantes no lo retrasarán mucho en un caso tan raro.
Normalmente, buscará parches o grupos de filas que se hayan ingresado en secuencia o proximidad y compartirá páginas de datos. Esas filas se extienden debido al desorden, se deben leer más páginas de disco para satisfacer su consulta. Tener que leer más páginas suele ser la razón más importante para que una consulta sea más lenta. Y ese es el factor más importante por el cual las columnas irrelevantes hacen que sus consultas sean más lentas.
Con grandes bases de datos, normalmente no hay suficiente RAM para mantener todo en la memoria caché. Las filas más grandes ocupan más caché, más contención, menos aciertos de caché, más E / S de disco. Y las lecturas de disco suelen ser mucho más caras. Menos con los SSD, pero sigue habiendo una diferencia sustancial. Esto se suma al punto anterior sobre las lecturas de página.
Se puede o no importa si las columnas son irrelevantes TOSTADA-ed. Las columnas relevantes también pueden ser TOAST-ed, devolviendo el mismo efecto.
fuente
Una pequeña prueba:
Limitar la consulta a las primeras 250 filas (
WHERE num <= 250
) da como resultado 34.539 ms y 8.343 ms, respectivamente. Seleccionar todos menoslong_long_text
de este conjunto limitado da como resultado 18.432 ms. Esto muestra que, en sus términos, PG es lo suficientemente inteligente.fuente