PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Otimize o PostgreSQL para testes rápidos


Primeiro, sempre use a versão mais recente do PostgreSQL. As melhorias de desempenho estão sempre chegando, então você provavelmente está perdendo seu tempo se estiver ajustando uma versão antiga. Por exemplo, o PostgreSQL 9.2 melhora significativamente a velocidade de TRUNCATE e, claro, adiciona varreduras somente de índice. Mesmo lançamentos menores devem sempre ser seguidos; consulte a política de versão.

Não fazer


Faça NÃO coloque um tablespace em um disco RAM ou outro armazenamento não durável.

Se você perder um tablespace, todo o banco de dados pode ser danificado e difícil de usar sem um trabalho significativo. Há muito pouca vantagem nisso em comparação com apenas usar UNLOGGED tabelas e ter muita RAM para cache de qualquer maneira.

Se você realmente quer um sistema baseado em ramdisk, initdb um cluster totalmente novo no ramdisk por initdb uma nova instância do PostgreSQL no ramdisk, então você tem uma instância do PostgreSQL completamente descartável.

Configuração do servidor PostgreSQL


Ao testar, você pode configurar seu servidor para uma operação não durável, mas mais rápida.

Este é um dos únicos usos aceitáveis ​​para o fsync=off configuração no PostgreSQL. Essa configuração praticamente diz ao PostgreSQL para não se preocupar com gravações ordenadas ou qualquer outra coisa desagradável de proteção de integridade de dados e segurança contra falhas, dando permissão para destruir totalmente seus dados se você perder energia ou tiver uma falha no sistema operacional.

Escusado será dizer que você nunca deve habilitar fsync=off em produção, a menos que você esteja usando o Pg como um banco de dados temporário para dados que você pode gerar novamente de outro lugar. Se e somente se você estiver fazendo para desativar o fsync também pode ativar full_page_writes desligado, pois não adianta mais nada. Esteja ciente de que fsync=off e full_page_writes inscreva-se no cluster nível, então eles afetam todos bancos de dados em sua instância do PostgreSQL.

Para uso em produção, você pode usar synchronous_commit=off e defina um commit_delay , pois você terá muitos dos mesmos benefícios que fsync=off sem o risco gigante de corrupção de dados. Você tem uma pequena janela de perda de dados recentes se habilitar a confirmação assíncrona - mas é isso.

Se você tiver a opção de alterar um pouco o DDL, também poderá usar UNLOGGED tabelas na Pg 9.1+ para evitar completamente o log do WAL e obter um aumento real de velocidade ao custo das tabelas serem apagadas se o servidor travar. Não há opção de configuração para desconectar todas as tabelas, ela deve ser definida durante CREATE TABLE . Além de ser bom para testar, isso é útil se você tiver tabelas cheias de dados gerados ou sem importância em um banco de dados que, de outra forma, contém coisas que você precisa para estar seguro.

Verifique seus logs e veja se você está recebendo avisos sobre muitos pontos de verificação. Se estiver, você deve aumentar seus checkpoint_segments. Você também pode querer ajustar seu checkpoint_completion_target para suavizar as gravações.

Ajuste shared_buffers para se adequar à sua carga de trabalho. Isso depende do sistema operacional, depende do que mais está acontecendo com sua máquina e requer algumas tentativas e erros. Os padrões são extremamente conservadores. Pode ser necessário aumentar o limite máximo de memória compartilhada do SO se você aumentar shared_buffers no PostgreSQL 9.2 e abaixo; 9.3 e acima mudaram como eles usam a memória compartilhada para evitar isso.

Se você estiver usando apenas algumas conexões que fazem muito trabalho, aumente work_mem para dar a eles mais memória RAM para jogar, etc. Cuidado com um work_mem muito alto A configuração pode causar problemas de falta de memória porque é por classificação e não por conexão, portanto, uma consulta pode ter muitas classificações aninhadas. Você só realmente tem que aumentar work_mem se você puder ver as classificações se espalhando para o disco em EXPLAIN ou logado com os log_temp_files configuração (recomendado), mas um valor mais alto também pode permitir que Pg escolha planos mais inteligentes.

Como dito por outro postador aqui, é aconselhável colocar o xlog e as tabelas/índices principais em HDDs separados, se possível. Partições separadas é bastante inútil, você realmente quer unidades separadas. Essa separação tem muito menos benefícios se você estiver executando com fsync=off e quase nenhum se você estiver usando UNLOGGED mesas.

Por fim, ajuste suas consultas. Certifique-se de que seu random_page_cost e seq_page_cost refletem o desempenho do seu sistema, certifique-se de que seu effective_cache_size está correto, etc. Use EXPLAIN (BUFFERS, ANALYZE) para examinar planos de consulta individuais e ativar o auto_explain módulo para relatar todas as consultas lentas. Muitas vezes, você pode melhorar drasticamente o desempenho da consulta apenas criando um índice apropriado ou ajustando os parâmetros de custo.

AFAIK não há como definir um banco de dados ou cluster inteiro como UNLOGGED . Seria interessante poder fazê-lo. Considere perguntar na lista de discussão do PostgreSQL.

Ajuste do SO do host


Há alguns ajustes que você pode fazer no nível do sistema operacional também. A principal coisa que você pode querer fazer é convencer o sistema operacional a não liberar gravações no disco de forma agressiva, já que você realmente não se importa quando/se eles chegam ao disco.

No Linux você pode controlar isso com o dirty_* do subsistema de memória virtual configurações, como dirty_writeback_centisecs .

O único problema com o ajuste das configurações de write-back para serem muito frouxas é que um flush de algum outro programa pode fazer com que todos os buffers acumulados do PostgreSQL sejam liberados também, causando grandes travamentos enquanto tudo é bloqueado nas gravações. Você pode aliviar isso executando o PostgreSQL em um sistema de arquivos diferente, mas alguns flushes podem ser em nível de dispositivo ou em nível de host inteiro e não em nível de sistema de arquivos, então você não pode confiar nisso.

Esse ajuste realmente requer brincar com as configurações para ver o que funciona melhor para sua carga de trabalho.

Em kernels mais novos, você pode querer garantir que vm.zone_reclaim_mode é definido como zero, pois pode causar sérios problemas de desempenho com sistemas NUMA (a maioria dos sistemas atualmente) devido a interações com a forma como o PostgreSQL gerencia shared_buffers .

Ajuste de consulta e carga de trabalho


Estas são coisas que requerem mudanças de código; eles podem não se adequar a você. Algumas são coisas que você pode aplicar.

Se você não estiver agrupando trabalho em lotes em transações maiores, comece. Muitas transações pequenas são caras, então você deve agrupar coisas sempre que for possível e prático fazê-lo. Se você estiver usando a confirmação assíncrona, isso é menos importante, mas ainda é altamente recomendado.

Sempre que possível, use tabelas temporárias. Eles não geram tráfego WAL, então são muito mais rápidos para inserções e atualizações. Às vezes, vale a pena colocar um monte de dados em uma tabela temporária, manipulá-los da maneira que você precisar e, em seguida, fazer um INSERT INTO ... SELECT ... para copiá-lo para a mesa final. Observe que as tabelas temporárias são por sessão; se sua sessão terminar ou você perder sua conexão, a tabela temporária desaparecerá e nenhuma outra conexão poderá ver o conteúdo da(s) tabela(s) temporária(s) de uma sessão.

Se você estiver usando o PostgreSQL 9.1 ou mais recente, você pode usar UNLOGGED tabelas para dados que você pode perder, como o estado da sessão. Eles são visíveis em diferentes sessões e preservados entre as conexões. Eles são truncados se o servidor for desligado de forma imprópria para que não possam ser usados ​​para nada que você não possa recriar, mas são ótimos para caches, visualizações materializadas, tabelas de estado etc.

Em geral, não DELETE FROM blah; . Use TRUNCATE TABLE blah; em vez de; é muito mais rápido quando você está despejando todas as linhas em uma tabela. Truncar muitas tabelas em um TRUNCATE ligue se puder. Há uma ressalva se você estiver fazendo muitos TRUNCATES de pequenas mesas uma e outra vez, no entanto; veja:Velocidade de truncamento do Postgresql

Se você não tiver índices em chaves estrangeiras, DELETE s envolvendo as chaves primárias referenciadas por essas chaves estrangeiras serão terrivelmente lentos. Certifique-se de criar esses índices se você espera DELETE da(s) tabela(s) referenciada(s). Índices não são necessários para TRUNCATE .

Não crie índices que você não precisa. Cada índice tem um custo de manutenção. Tente usar um conjunto mínimo de índices e deixe que as varreduras de índice de bitmap os combinem em vez de manter muitos índices de várias colunas enormes e caros. Onde os índices são necessários, tente preencher a tabela primeiro e, em seguida, crie índices no final.

Hardware


Ter RAM suficiente para armazenar todo o banco de dados é uma grande vitória se você puder gerenciá-lo.

Se você não tiver RAM suficiente, quanto mais rápido o armazenamento, melhor. Mesmo um SSD barato faz uma enorme diferença em relação à ferrugem giratória. No entanto, não confie em SSDs baratos para produção, eles geralmente não são à prova de falhas e podem consumir seus dados.

Aprendizagem


O livro de Greg Smith, PostgreSQL 9.0 High Performance permanece relevante apesar de se referir a uma versão um pouco mais antiga. Deve ser uma referência útil.

Junte-se à lista de discussão geral do PostgreSQL e siga-a.

Leitura:

  • Ajustando seu servidor PostgreSQL - wiki PostgreSQL
  • Número de conexões de banco de dados - wiki do PostgreSQL