AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 18864
Accepted
Jmoney38
Jmoney38
Asked: 2012-06-06 12:52:08 +0800 CST2012-06-06 12:52:08 +0800 CST 2012-06-06 12:52:08 +0800 CST

O que é recuperado do disco durante uma consulta?

  • 772

Pergunta bastante simples, provavelmente respondida em algum lugar, mas não consigo formular 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 um subconjunto dessa tabela?

Por exemplo, se a tabela Foo tiver 20 colunas, mas minha consulta selecionar apenas 5 dessas colunas, ter 20 (versus, digamos, 10) colunas afetará o desempenho da consulta? Para simplificar, suponha 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. Perco muito a compreensão do design de armazenamento físico do Postgres. As tabelas são armazenadas em várias páginas (o padrão é 8k de tamanho por página), mas não entendo muito bem como as tuplas são organizadas a partir daí. O PG é inteligente o suficiente para buscar apenas no disco os dados que compreendem essas 5 colunas?

postgresql performance
  • 3 3 respostas
  • 2471 Views

3 respostas

  • Voted
  1. Best Answer
    Daniel Vérité
    2012-06-07T04:59:49+08:002012-06-07T04:59:49+08:00

    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 são todos armazenados na mesma página de disco, com exceção notável do conteúdo TOAST 'ed (grande demais para caber em uma página). Os conteúdos são extraídos sequencialmente dentro de cada linha, conforme explicado:

    Para ler os dados, você precisa examinar cada atributo por vez. Primeiro verifique se o campo é NULL de acordo com o bitmap nulo. Se for, vá para o próximo. Em seguida, certifique-se de ter o alinhamento correto. Se o campo for de largura fixa, todos os bytes serão simplesmente colocados.

    No caso mais simples (sem colunas TOAST'ed), o postgres buscará a linha inteira, mesmo que poucas colunas sejam necessárias. Portanto, neste caso, a resposta é sim, ter mais colunas pode ter um claro impacto adverso no cache do buffer de desperdício, especialmente se o conteúdo da coluna for grande enquanto ainda estiver abaixo do limite 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. Ele também entra em jogo quando a linha inteira não cabe em uma página (8kB por padrão): alguns dos campos são movidos para o armazenamento TOAST. Doc diz:

    Se for um campo de comprimento variável (attlen = -1), é um pouco mais complicado. Todos os tipos de dados de comprimento variável compartilham a estrutura de cabeçalho comum struct varlena, que inclui o comprimento total do valor armazenado e alguns bits de sinalizador. Dependendo dos sinalizadores, os dados podem estar embutidos ou em uma tabela TOAST; pode ser compactado também

    Os conteúdos TOAST não são buscados quando não são explicitamente necessários, então seu efeito no número total de páginas a serem buscadas é pequeno (alguns bytes por coluna). Isso explica os resultados da resposta de @dezso.

    Quanto às gravações, cada linha com todas as suas colunas é totalmente reescrita em cada UPDATE, independentemente das colunas alteradas. Portanto, ter mais colunas é obviamente mais caro para as gravações.

    • 19
  2. Erwin Brandstetter
    2012-06-08T15:23:31+08:002012-06-08T15:23:31+08:00

    A resposta de Daniel se concentra no custo da leitura de linhas individuais. Neste contexto: Colocar NOT NULLcolunas de tamanho fixo primeiro em sua tabela ajuda um pouco. Colocar as colunas relevantes primeiro (aquelas que você consulta) ajuda um pouco. Minimizar o preenchimento (devido ao alinhamento de dados) jogando tetris de alinhamento com suas colunas pode ajudar um pouco. Mas o efeito mais importante ainda não foi mencionado, especialmente para mesas grandes.

    Colunas adicionais obviamente fazem com que uma linha cubra mais espaço em disco, de modo que menos linhas caibam em uma página de dados (8 kB por padrão). Linhas individuais sã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 tenha que ser lido.

    Se uma consulta buscar uma porção (relativamente) pequena de uma grande tabela, onde as linhas estão espalhadas mais ou menos aleatoriamente por toda a tabela, suportadas por um índice, isso resultará aproximadamente no mesmo número de páginas lidas, com pouca consideração para o tamanho da linha. Colunas irrelevantes não vão atrasá-lo muito nesse caso (raro).

    Normalmente, você buscará patches ou grupos de linhas que foram inseridas em sequência ou proximidade e compartilhará páginas de dados. Essas linhas estão espalhadas devido à desordem, mais páginas do disco precisam ser lidas para satisfazer sua consulta. Ter que ler mais páginas é normalmente o motivo mais importante para uma consulta ser mais lenta. E esse é o fator mais importante pelo qual colunas irrelevantes tornam suas consultas mais lentas.

    Com bancos de dados grandes, 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 são normalmente muito mais caras. Menos com SSDs, mas uma diferença substancial permanece. Isso aumenta o ponto acima sobre leituras de página.

    Pode ou não importar se as colunas irrelevantes são TOAST-ed. As colunas relevantes também podem ser TOAST-ed, trazendo de volta muito do mesmo efeito.

    • 11
  3. dezso
    2012-06-06T13:50:05+08:002012-06-06T13:50:05+08:00

    Um pequeno teste:

    CREATE TABLE test2 (
        id serial PRIMARY KEY,
        num integer,
        short_text varchar(32),
        longer_text varchar(1000),
        long_long_text text
    );
    
    INSERT INTO test2 (num, short_text, longer_text, long_long_text)
    SELECT i, lpad('', 32, 'abcdefeghji'), lpad('', 1000, 'abcdefeghji'), lpad('', (random() * 10000)::integer, 'abcdefeghji')
    FROM generate_series(1, 10000) a(i);
    
    ANALYZE test2;
    
    SELECT * FROM test2;
    [...]
    Time: 1091.331 ms
    
    SELECT num FROM test2;
    [...]
    Time: 21.310 ms
    

    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, exceto long_long_textdeste conjunto limitado, resulta em 18,432 ms. Isso mostra que, em seus termos, o PG é inteligente o suficiente.

    • 1

relate perguntas

  • Sequências Biológicas do UniProt no PostgreSQL

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve