Primeiro, sempre use a versão mais recente do PostgreSQL. As melhorias de desempenho estão sempre chegando; portanto, você provavelmente está perdendo tempo se estiver ajustando uma versão antiga. Por exemplo, o PostgreSQL 9.2 melhora significativamente a velocidadeTRUNCATE
e, naturalmente, adiciona varreduras somente de índice. Mesmo versões menores sempre devem ser seguidas; consulte a política de versão .
Não é
Você não colocar um espaço de tabela em um disco RAM ou outro armazenamento não-duráveis .
Se você perder um espaço de tabela, todo o banco de dados poderá ser danificado e difícil de usar sem um trabalho significativo. Há muito pouca vantagem nisso se comparado ao uso de UNLOGGED
tabelas e à disponibilidade de muita RAM para cache.
Se você realmente deseja um sistema baseado em ramdisk, initdb
um cluster totalmente novo no ramdisk, initdb
inserindo uma nova instância do PostgreSQL no ramdisk, para ter 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 a 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 à integridade de dados e segurança contra falhas, dando permissão para descartar totalmente seus dados se você perder energia ou ocorrer uma falha no sistema operacional.
Desnecessário dizer que você nunca deve ativar a fsync=off
produção, a menos que esteja usando a 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 é possível full_page_writes
desativar, pois não serve mais para nada. Cuidado fsync=off
e full_page_writes
aplique no nível do cluster , para que eles afetem todos os bancos de dados na sua instância do PostgreSQL.
Para uso em produção, é possível usar synchronous_commit=off
e definir 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 ativar a confirmação assíncrona - mas é isso.
Se você tiver a opção de alterar levemente o DDL, também poderá usar as UNLOGGED
tabelas na página 9.1+ para evitar completamente o log do WAL e obter um aumento real da velocidade com o custo de as tabelas serem apagadas se o servidor travar. Não há opção de configuração para tornar todas as tabelas desmarcadas; 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 estar seguro.
Verifique seus logs e veja se você está recebendo avisos sobre muitos pontos de verificação. Se você é, você deve aumentar seus pontos de verificação . Você também pode ajustar seu checkpoint_completion_target para facilitar as gravações.
Ajuste shared_buffers
para ajustar 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 sistema operacional se você aumentar shared_buffers
no PostgreSQL 9.2 e abaixo; 9.3 e acima mudaram a maneira como eles usam a memória compartilhada para evitar isso.
Se você estiver usando apenas algumas conexões que dão muito trabalho, aumente work_mem
para fornecer mais memória RAM para brincar, etc. Lembre-se de que uma work_mem
configuração muito alta pode causar problemas de falta de memória porque ela não é classificada por categoria. por conexão para que uma consulta possa ter várias classificações aninhadas. Você realmente precisa aumentar work_mem
se conseguir ver as classificações sendo derramadas no disco EXPLAIN
ou logadas com a log_temp_files
configuração (recomendável), mas um valor mais alto também pode permitir que a Pg escolha planos mais inteligentes.
Como dito por outro pôster aqui, é aconselhável colocar o xlog e as tabelas / índices principais em HDDs separados, se possível. Partições separadas são inúteis, você realmente deseja unidades separadas. Essa separação tem muito menos benefícios se você estiver executando com fsync=off
e quase nenhum se estiver usando UNLOGGED
tabelas.
Por fim, ajuste suas consultas. Verifique random_page_cost
e seq_page_cost
reflita o desempenho do seu sistema, verifique se effective_cache_size
está correto, etc. Use EXPLAIN (BUFFERS, ANALYZE)
para examinar planos de consulta individuais e ligue o auto_explain
módulo para relatar todas as consultas lentas. Muitas vezes, é possível melhorar drasticamente o desempenho da consulta criando um índice apropriado ou aprimorando os parâmetros de custo.
AFAIK não há como definir um banco de dados ou cluster inteiro como UNLOGGED
. Seria interessante poder fazer isso. Considere perguntar na lista de discussão do PostgreSQL.
Ajuste do SO do host
Também é possível fazer alguns ajustes no nível do sistema operacional. A principal coisa que você pode querer fazer é convencer o sistema operacional a não liberar gravações no disco de forma agressiva, pois você realmente não se importa quando / se elas o fazem no disco.
No Linux, você pode controlar isso com o subsistema de memória virtual 's dirty_*
configurações, como dirty_writeback_centisecs
.
O único problema com o ajuste das configurações de write-back é muito frouxo é que uma descarga por outro programa pode causar a descarga de todos os buffers acumulados do PostgreSQL também, causando grandes paradas enquanto tudo bloqueia as gravações. Você pode aliviar isso executando o PostgreSQL em um sistema de arquivos diferente, mas algumas descargas podem ser no nível do dispositivo ou no host inteiro e não no sistema de arquivos, portanto você não pode confiar nisso.
Esse ajuste realmente exige que você faça as configurações para ver o que funciona melhor para sua carga de trabalho.
Nos kernels mais recentes, convém garantir que vm.zone_reclaim_mode
seja definido como zero, pois isso pode causar problemas graves de desempenho nos sistemas NUMA (na maioria dos sistemas atualmente) devido a interações com o gerenciamento do PostgreSQL shared_buffers
.
Ajuste de consulta e carga de trabalho
São coisas que exigem alterações de código; eles podem não combina com você. Algumas são coisas que você pode aplicar.
Se você não estiver trabalhando em lotes em transações maiores, inicie. Muitas transações pequenas são caras, portanto, você deve agrupar as coisas sempre que possível e prático. 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, portanto, são muito mais rápidos para inserções e atualizações. Às vezes, vale a pena incluir um monte de dados em uma tabela temporária, manipulá-los da maneira que você precisar e, em seguida, fazer uma INSERT INTO ... SELECT ...
cópia para a tabela final. Observe que as tabelas temporárias são por sessão; se a sua sessão terminar ou você perder a conexão, a tabela temporária desaparecerá e nenhuma outra conexão poderá ver o conteúdo das tabelas temporárias de uma sessão.
Se você estiver usando o PostgreSQL 9.1 ou mais recente, poderá usar UNLOGGED
tabelas para dados que 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 maneira não limpa, para que não possam ser usados para qualquer coisa 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 em TRUNCATE TABLE blah;
vez disso; é muito mais rápido quando você descarta todas as linhas em uma tabela. Trunque muitas tabelas em uma TRUNCATE
chamada, se puder. Há uma ressalva se você estiver fazendo muitas TRUNCATES
mesas pequenas repetidamente; veja: Velocidade de truncamento do Postgresql
Se você não tiver índices em chaves estrangeiras, os DELETE
s que envolvem as chaves primárias referenciadas por essas chaves estrangeiras serão terrivelmente lentos. Crie esses índices, se você espera DELETE
da tabela (s) referenciada (s). Os índices não são necessários para TRUNCATE
.
Não crie índices desnecessários. Cada índice tem um custo de manutenção. Tente usar um conjunto mínimo de índices e permita que as varreduras de índice de bitmap as combinem, em vez de manter muitos índices enormes e caros de várias colunas. Onde os índices são necessários, tente preencher a tabela primeiro e depois 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. Porém, não confie em SSDs baratos para produção, eles geralmente não são seguros contra falhas e podem consumir seus dados.
Aprendendo
O livro de Greg Smith, PostgreSQL 9.0 High Performance, continua relevante, apesar de se referir a uma versão um pouco mais antiga. Deve ser uma referência útil.
Entre na lista de discussão geral do PostgreSQL e siga-a.
Lendo: