Pode ser necessário inserir uma grande quantidade de dados ao se fazer a carga inicial do banco de dado. Esta seção contém algumas sugestões sobre como tornar este processo tão eficiente quanto possível.
Desativar a efetivação automática (autocommit) e fazer apenas uma efetivação no final (Em puro SQL, isto significa executar BEGIN no começo e COMMIT no fim. Algumas bibliotecas cliente podem fazer isto às escondidas e, neste caso, é preciso ter certeza que a biblioteca só faz quando se deseja que seja feito). Se permitirmos efetivar cada inserção separadamente, o PostgreSQL terá muito trabalho para cada linha inserida. Um benefício adicional de fazer todas as inserções em uma transação, é que se a inserção de uma linha não for bem-sucedida, então a inserção de todas as linhas feita até este ponto é desfeita, não sendo necessário se preocupar com a carga parcial dos dados.
Usar o comando COPY para carregar todas as linhas em um comando, em vez de usar uma série de comandos INSERT. O comando COPY é otimizado para carregar uma grande quantidade de linhas; é menos flexível que o comando INSERT, mas ocasiona uma sobrecarga significativamente menor para cargas de dados volumosas. Uma vez que o comando COPY é um único comando, não é necessário desativar a auto-efetivação se for utilizado este método para carregar a tabela.
Se não for possível utilizar o comando COPY, pode ser útil utilizar o comando PREPARE para criar comandos INSERT preparados, e depois usar o comando EXECUTE tantas vezes quanto forem necessárias. Isto evita a sobrecarga de analisar e planejar o comando INSERT repetidas vezes.
Deve-se notar que carregar uma grande quantidade de linhas utilizando o comando COPY é quase sempre mais rápido que utilizando o comando INSERT, mesmo que o comando PREPARE seja utilizado e sejam feitas várias inserções em lote em uma única transação.
Se estiver sendo carregada uma tabela recém criada, a maneira mais rápida é criar a tabela, carregar os dados usando o COPY e, depois, criar os índices necessários para a tabela. Criar um índice sobre dados pré-existentes é mais rápido que atualizá-lo de forma incremental durante a carga de cada linha.
Para aumentar uma tabela existente, pode-se remover o índice, carregar a tabela e, depois, recriar o índice. É claro que o desempenho do banco de dados para os outros usuários será afetado negativamente durante o tempo que o índice não existir. Deve-se pensar duas vezes antes de remover um índice único, porque a verificação de erro efetuada pela restrição de unicidade não existirá enquanto o índice não tiver sido criado novamente.
O aumento temporário da variável de configuração maintenance_work_mem durante a carga de uma grande quantidade de dados pode ocasionar uma melhora no desempenho. Isto se deve ao fato de quando o índice B-tree é criado a partir do início, o conteúdo presente na tabela precisa ser ordenado. Permitir o "merge sort" [1] utilizar mais memória significa que serão necessários menos passos de mesclagem. Uma definição maior para maintenance_work_mem também pode acelerar a validação de restrições de chave estrangeira.
O aumento temporário da variável de configuração checkpoint_segments também pode tornar as cargas de dados volumosas mais rápidas. Isto se deve ao fato de quando uma grande quantidade de dados é carregada no PostgreSQL, isto pode fazer com que os pontos de verificação (checkpoints) ocorram com mais freqüência que a freqüência normal de ponto de verificação (especificada pela variável de configuração checkpoint_timeout). Sempre que ocorre um ponto de verificação, todas as páginas sujas (dirty pages) devem ser descarregadas no disco. Aumentado-se checkpoint_segments temporariamente durante uma carga volumosa, o número de pontos de verificação necessários pode ser menor.
Após se alterar significativamente a distribuição dos dados da tabela, é recomendado executar o comando ANALYZE. Isto inclui a carga de grande quantidade de dados na tabela. A execução do comando ANALYZE (ou VACUUM ANALYZE) garante que o planejador possuirá estatísticas atualizadas sobre a tabela. Sem estatísticas, ou com estatísticas obsoletas, o planejador pode tomar decisões ineficientes durante o planejamento dos comandos, ocasionando um desempenho fraco nas tabelas com estatísticas imprecisas ou não existentes.
[1] |
merge sort — Um algoritmo de classificação que divide os itens a serem classificados em dois grupos, classifica cada grupo recursivamente e, depois, mescla os grupos em uma seqüência classificada final. Dictionary of Algorithms and Data Structures (N. do T.) |