Pergunta bastante simples, provavelmente respondida em algum lugar, mas não consigo formar a pergunta de pesquisa correta para o Google ...
O número de colunas em uma tabela específica afeta o desempenho de uma consulta ao consultar em um subconjunto dessa tabela?
Por exemplo, se a tabela Foo possui 20 colunas, mas minha consulta seleciona apenas 5 dessas colunas, ter 20 (versus, digamos, 10) colunas afeta o desempenho da consulta? Suponha, por simplicidade, que qualquer coisa na cláusula WHERE esteja incluída nessas 5 colunas.
Estou preocupado com o uso do cache de buffer do Postgres, além do cache de disco do sistema operacional. Perdi muito a noção do design de armazenamento físico do Postgres. As tabelas são armazenadas em várias páginas (com tamanho padrão de 8k por página), mas não entendo como as tuplas são organizadas a partir daí. O PG é inteligente o suficiente para buscar apenas do disco os dados que compõem essas 5 colunas?
fonte
Respostas:
O armazenamento físico para linhas é descrito nos documentos em Layout de página do banco de dados . O conteúdo da coluna para a mesma linha é todo armazenado na mesma página do disco, com a exceção notável do TOAST conteúdo (muito grande para caber em uma página). O conteúdo é extraído sequencialmente dentro de cada linha, conforme explicado:
No caso mais simples (sem colunas TOAST), o postgres buscará a linha inteira, mesmo que sejam necessárias poucas colunas. Portanto, nesse caso, a resposta é sim, ter mais colunas pode ter um claro impacto adverso no cache do buffer do waster, principalmente se o conteúdo da coluna for grande enquanto ainda estiver abaixo do limite do TOAST.
Agora, o caso TOAST: quando um campo individual excede ~ 2kB, o mecanismo armazena o conteúdo do campo em uma tabela física separada. Também entra em ação quando a linha inteira não se encaixa em uma página (8kB por padrão): alguns dos campos são movidos para o armazenamento TOAST. Doc diz:
O conteúdo do TOAST não é buscado quando não é explicitamente necessário; portanto, seu efeito no número total de páginas a serem buscadas é pequeno (alguns bytes por coluna). Isso explica os resultados na resposta do @ dezso.
Quanto às gravações, cada linha com todas as suas colunas é totalmente reescrita em cada UPDATE, independentemente de quais colunas sejam alteradas. Portanto, ter mais colunas é obviamente mais caro para gravações.
fonte
A resposta de Daniel se concentra no custo da leitura de linhas individuais. Nesse contexto: Colocar
NOT NULL
colunas de tamanho fixo em primeiro lugar em sua tabela ajuda um pouco. Colocar as colunas relevantes em primeiro lugar (as que você consulta) ajuda um pouco. Minimização do preenchimento (devido ao alinhamento de dados) tocando o tetris de alinhamento com suas colunas pode ajudar um pouco. Mas o efeito mais importante ainda não foi mencionado, especialmente para grandes mesas.Colunas adicionais obviamente fazem com que uma linha cubra mais espaço em disco, para que menos linhas caibam em uma página de dados (8 kB por padrão). Linhas individuais estão espalhadas por mais páginas. O mecanismo de banco de dados geralmente precisa buscar páginas inteiras, não linhas individuais . Pouco importa se as linhas individuais são um pouco menores ou maiores - desde que o mesmo número de páginas precise ser lido.
Se uma consulta buscar uma parte (relativamente) pequena de uma tabela grande, onde as linhas estão espalhadas mais ou menos aleatoriamente por toda a tabela, suportada por um índice, isso resultará em aproximadamente o mesmo número de leituras de página, com pouca consideração para tamanho de linha. Colunas irrelevantes não o atrasarão muito nesse caso (raro).
Normalmente, você busca patches ou agrupamentos de linhas que foram inseridos em sequência ou proximidade e compartilha páginas de dados. Essas linhas são espalhadas devido à confusão, mais páginas do disco precisam ser lidas para satisfazer sua consulta. Ter que ler mais páginas geralmente é o motivo mais importante para uma consulta ser mais lenta. E esse é o fator mais importante por que colunas irrelevantes tornam suas consultas mais lentas.
Com grandes bancos de dados, normalmente não há RAM suficiente para manter tudo na memória cache. Linhas maiores ocupam mais cache, mais contenção, menos ocorrências de cache, mais E / S de disco. E as leituras de disco geralmente são muito mais caras. Menos com os SSDs, mas uma diferença substancial permanece. Isso adiciona ao ponto acima sobre leituras de página.
Ele pode ou não importa se colunas irrelevantes são BRINDE-ed. As colunas relevantes também podem ser editadas pelo TOAST, trazendo de volta praticamente o mesmo efeito.
fonte
Um pequeno teste:
Limitar a consulta às primeiras 250 linhas (
WHERE num <= 250
) resulta em 34.539 ms e 8.343 ms, respectivamente. A seleção de todos, excetolong_long_text
deste conjunto limitado, resulta em 18,432 ms. Isso mostra que, nos seus termos, o PG é inteligente o suficiente.fonte