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

Otimizar intervalo de consulta de carimbo de data/hora do Postgres

CLUSTER


Se você pretende usar CLUSTER , a sintaxe exibida é inválida.

criar tíquete CLUSTER USANDO ticket_1_idx;

Executar Uma Vez:
CLUSTER ticket USING ticket_1_idx;

Isso pode ajudam muito com conjuntos de resultados maiores. Não tanto para uma única linha retornada.
O Postgres lembra qual índice usar para chamadas subseqüentes. Se sua tabela não for somente leitura, o efeito se deteriora com o tempo e você precisa executar novamente em determinados intervalos:
CLUSTER ticket;

Possivelmente apenas em partições voláteis. Ver abaixo.

No entanto , se você tiver muitas atualizações, CLUSTER (ou VACUUM FULL ) pode realmente ser ruim para o desempenho. A quantidade certa de inchaço permite UPDATE para colocar novas versões de linha na mesma página de dados e evita a necessidade de estender fisicamente o arquivo subjacente no sistema operacional com muita frequência. Você pode usar um FILLFACTOR cuidadosamente ajustado para obter o melhor dos dois mundos:
  • Fator de preenchimento para um índice sequencial que é PK

pg_repack


CLUSTER leva um bloqueio exclusivo na mesa, o que pode ser um problema em um ambiente multiusuário. Citando o manual:

Quando uma tabela está sendo agrupada, um ACCESS EXCLUSIVE bloqueio é adquirido nele. Isso impede qualquer outra operação de banco de dados (tanto leitura quanto gravação ) de operar na tabela até o CLUSTER está terminado.

Minha ênfase em negrito. Considere a alternativa pg_repack :

Ao contrário de CLUSTER e VACUUM FULL funciona online, sem travar exclusivo nas tabelas processadas durante o processamento. pg_repack é eficiente para inicializar, com desempenho comparável ao uso de CLUSTER diretamente.

e:

O pg_repack precisa ter um bloqueio exclusivo ao final da reorganização.

A versão 1.3.1 funciona com:

PostgreSQL 8.3, 8.4, 9.0, 9.1, 9.2, 9.3, 9.4

A versão 1.4.2 funciona com:

PostgreSQL 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 10

Consulta


A consulta é simples o suficiente para não causar problemas de desempenho por si só.

No entanto, uma palavra sobre correção :O ENTRE construção inclui fronteiras. Sua consulta seleciona todos de 19 de dezembro, mais registros de 20 de dezembro, 00:00 horas. Isso é extremamente improvável requerimento. É provável que você realmente queira:
SELECT *
FROM   ticket 
WHERE  created >= '2012-12-19 0:0'
AND    created <  '2012-12-20 0:0';

Desempenho


Antes de mais nada, você pergunta:

Por que está selecionando varredura sequencial?

Seu EXPLICAR a saída mostra claramente uma Varredura de índice , não uma varredura de tabela sequencial. Deve haver algum tipo de mal-entendido.

Se você for pressionado por um melhor desempenho, poderá melhorar as coisas. Mas a informação de fundo necessária não está em questão. As opções possíveis incluem:

  • Você só pode consultar colunas obrigatórias em vez de * para reduzir o custo de transferência (e possivelmente outros benefícios de desempenho).

  • Você pode ver particionamento e coloque fatias de tempo práticas em tabelas separadas. Adicione índices às partições conforme necessário.

  • Se o particionamento não for uma opção, outra técnica relacionada, mas menos intrusiva, seria adicionar um ou mais índices parciais .
    Por exemplo, se você consultar principalmente o mês atual , você pode criar o seguinte índice parcial:
    CREATE INDEX ticket_created_idx ON ticket(created)
    WHERE created >= '2012-12-01 00:00:00'::timestamp;
    

    CRIAR um novo índice antes o início de um novo mês. Você pode automatizar facilmente a tarefa com um cron job. Opcionalmente DROP índices parciais para meses antigos depois.

  • Mantenha o índice total adicional para CLUSTER (que não pode operar em índices parciais). Se os registros antigos nunca forem alterados, o particionamento de tabelas ajudaria muito nessa tarefa, pois você só precisa agrupar novamente as partições mais recentes. .

Se você combinar as duas últimas etapas, o desempenho deve ser incrível.

Noções básicas de desempenho


Você pode estar perdendo um dos fundamentos. Todos os conselhos de desempenho usuais se aplicam:
  • https://wiki.postgresql.org/wiki/Slow_Query_Questions
  • https://wiki.postgresql.org/wiki/Performance_Optimization