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 / 113149
Accepted
bobocopy
bobocopy
Asked: 2015-09-04 12:47:02 +0800 CST2015-09-04 12:47:02 +0800 CST 2015-09-04 12:47:02 +0800 CST

As linhas de largura fixa melhoram o desempenho de leitura do PostgreSQL?

  • 772

tenho uma tabela articles:

                                                       Table "articles"
     Column     |            Type             |                     Modifiers                      | Storage  | Stats target | Description
----------------+-----------------------------+----------------------------------------------------+----------+--------------+-------------
 id             | integer                     | not null default nextval('articles_id_seq'::regclass) | plain    |              |
 user_id        | integer                     |                                                    | plain    |              |
 title          | character varying(255)      |                                                    | extended |              |
 author         | character varying(255)      |                                                    | extended |              |
 body           | text                        | default '--- []                                   +| extended |              |
                |                             | '::text                                            |          |              |
 created_at     | timestamp without time zone |                                                    | plain    |              |
 updated_at     | timestamp without time zone |                                                    | plain    |              |
 published_date | timestamp without time zone |                                                    | plain    |              |

Indexes:
    "articles_pkey" PRIMARY KEY, btree (id)
    "index_articles_on_published_date" btree (published_date)
    "index_rents_on_user_id" btree (user_id)
    "index_articles_on_user_id_and_published_date" btree (user_id, published_date)

Estamos no Postgres 9.4.4. A máquina tem 3,5 GB de memória e 150 GB de espaço em disco em um SSD.

Nota: O 'published_date' é sempre arredondado, pela aplicação, para a data mais próxima. Todas as horas/minutos/segundos são sempre 00. Legacy. Necessidades corrigidas. etc.

Esta tabela tem centenas de milhões de artigos. A tabela recebe uma grande quantidade de consultas de leitura de (até 16) processos simultâneos executando as seguintes consultas tão rapidamente quanto nosso sistema responderá:

  • uma contagem do número total de artigos

    SELECT COUNT(*) FROM articles;
    
  • uma seleção de todos os artigos publicados para um determinado usuário

    SELECT * FROM articles WHERE user_id = $1;
    
  • uma seleção do artigo publicado mais recentemente para um determinado usuário

    SELECT * FROM articles WHERE user_id = $1 ORDER BY published_date DESC LIMIT 1;
    

Estou descobrindo que, com um grande número de trabalhadores, essas consultas são bastante lentas. (No pico de carga, o primeiro leva minutos para ser concluído; os outros dois são da ordem de 10 segundos.) Em particular, parece que as consultas estão sendo enfileiradas.

A questão

Em resumo, as tabelas com apenas valores de largura fixa executam consultas de leitura melhor do que aquelas com larguras variadas? (Finja que o espaço em disco não é um problema.) No meu caso, estou me perguntando se veria uma melhoria de desempenho se extraísse o campo de texto 'corpo' para uma tabela separada e transformasse os campos de variação de caracteres em largura fixa campos de caracteres.

Admito que a pergunta é um pouco culta à carga. Eu simplesmente não sei o suficiente sobre os componentes internos do mecanismo de banco de dados Postgres para construir uma hipótese informada. Pretendo realizar experimentos reais com diferentes esquemas e configurações, mas gostaria de ter um modelo mental sólido de como o Postgres realmente funciona antes de prosseguir.

Pergunta relacionada

Onde posso aprender mais sobre os componentes internos do mecanismo de banco de dados Postgres? Eu pesquisei variações da pergunta acima com pouco sucesso. Quais são os termos corretos a serem usados ​​para esta pesquisa? Esse nível de documentação existe apenas na fonte e nas mentes dos DBAs Postgres? Também convido humildemente a sugestão de bons livros sobre o tema.

postgresql performance
  • 1 1 respostas
  • 2073 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2015-09-04T16:33:37+08:002015-09-04T16:33:37+08:00

    As tabelas com apenas valores de largura fixa executam consultas de leitura melhor do que aquelas com larguras variadas?

    Basicamente não. Existem custos muito pequenos ao acessar as colunas, mas você não poderá medir nenhuma diferença. Detalhes:

    • A ordem das colunas em uma tabela Postgres afeta o desempenho?

    Em particular:

    • Não há diferença de desempenho entre character varying(255)e text em tudo . Você parece ter a impressão de que varchar(255)(ao contrário textde ) pode ser um tipo de "largura fixa", mas não é assim. Ambos são tipos de comprimento variável, varchar(255)apenas adiciona uma verificação de comprimento máximo:
    • A pesquisa de índice seria visivelmente mais rápida com char vs varchar quando todos os valores forem 36 caracteres

    O uso de varchar(255)em uma definição de tabela geralmente indica uma falta de compreensão do sistema de tipos do Postgres. O arquiteto por trás disso provavelmente não é um falante nativo - ou o layout foi transferido de outro RDBMS como o SQL Server, onde isso costumava ser importante.

    • Sua consulta mais cara SELECT COUNT(*) FROM articlesnem sequer considera os dados da linha , apenas o tamanho total importa indiretamente. Contar todas as linhas é caro no Postgres devido ao seu modelo MVCC. Talvez uma estimativa seja boa o suficiente, que pode ser obtida muito barato ?
    • Maneira rápida de descobrir a contagem de linhas de uma tabela

    (Finja que o espaço em disco não é um problema.)

    O espaço em disco é sempre um problema, mesmo se você tiver muito. O tamanho do disco (número de páginas de dados que devem ser lidas/processadas/escritas) é um dos fatores mais importantes para o desempenho.

    Onde posso aprender mais sobre os componentes internos do mecanismo de banco de dados Postgres?

    A página de informações para a tag postgres tem os links mais importantes para mais informações, incluindo livros, o Postgres Wiki e o excelente manual. Este último é o meu favorito.

    Sua terceira consulta tem problemas

    SELECT * FROM articles WHERE user_id = $1 ORDER BY published_date DESC LIMIT 1;
    

    ORDER BY published_date DESC, mas published_datepode ser NULL (sem NOT NULLrestrição). Isso é uma arma de fogo carregada se pode haver valores NULL, a menos que você prefira valores NULL sobre o último real published_date.

    Adicione uma restriçãoNOT NULL . Sempre faça isso para colunas que não podem ser NULL.
    Ou faça isso ORDER BY published_date DESCNULLS LASTe adapte o índice de acordo.

    "articles_user_id_published_date_idx" btree (user_id, published_date DESC NULLS LAST)

    Detalhes nesta resposta relacionada recente:

    • Consulta extremamente lenta na coluna indexada no Postgres

    Converter published_datepara um realdate

    Enquanto 'published_date' is always rounded, é efetivamente apenas um dateque ocupa 4 bytes em vez de 8 para o timestamp. É melhor mover isso na definição da tabela para vir antes das duas timestampcolunas, para não perder os 4 bytes para o preenchimento:

    ...
    body           | text
    published_date | date   --     <---- here
    created_at     | timestamp without time zone
    updated_at     | timestamp without time zone
    

    O armazenamento em disco menor faz diferença no desempenho.

    • Configurando o PostgreSQL para desempenho de leitura

    Mais importante, seu índice (user_id, published_date)agora ocuparia apenas 32 bytes por entrada de índice em vez de 40, porque 2x4 bytes não incorrem em preenchimento extra. E isso faria uma diferença notável para o desempenho.

    Aparte: este índice não é relevante para as consultas demonstradas. Excluir, a menos que os índices, a menos que sejam usados ​​em outro lugar:

    "index_articles_on_published_date" btree (published_date)

    • 13

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

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 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

    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
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • 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
    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

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