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, umACCESS EXCLUSIVE
bloqueio é adquirido nele. Isso impede qualquer outra operação de banco de dados (tanto leitura quanto gravação ) de operar na tabela até oCLUSTER
está terminado.
Minha ênfase em negrito. Considere a alternativa
pg_repack
:
Ao contrário deCLUSTER
eVACUUM FULL
funciona online, sem travar exclusivo nas tabelas processadas durante o processamento. pg_repack é eficiente para inicializar, com desempenho comparável ao uso deCLUSTER
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. OpcionalmenteDROP
índices parciais para meses antigos depois.
-
Mantenha o índice total adicional paraCLUSTER
(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