Como posso forçar Postgres usar um índice particular?

votos
65

Como posso forçar Postgres usar um índice ao que seria de outra insistem em fazer uma varredura sequencial?

Publicado 21/11/2008 em 19:56
fonte usuário
Em outras línguas...                            


7 respostas

votos
68

Supondo que você está perguntando sobre o recurso comum "index insinuando" encontrado em muitos bancos de dados, o PostgreSQL não fornece essa funcionalidade. Esta foi uma decisão consciente feita pela equipe PostgreSQL. Uma boa visão geral do porquê eo que você pode fazer em vez disso pode ser encontrada aqui . As razões são, basicamente, que é um hack desempenho que tende a causar mais problemas mais tarde para baixo da linha, como as alterações de dados, enquanto otimizador do PostgreSQL pode re-avaliar o plano com base nas estatísticas. Em outras palavras, o que pode ser um plano de consulta bom hoje provavelmente não será um plano de consulta bom para todos os tempos, e dicas de índice forçar um plano de consulta particular para todos os tempos.

Como um martelo muito franco, útil para testar, você pode usar o enable_seqscane enable_indexscanparâmetros. Vejo:

Estes são não é adequado para uso em produção contínua . Se você tiver problemas com escolha plano de consulta, você deve ver a documentação para rastrear problemas de desempenho de consulta . Não basta definir enable_parâmetros e ir embora.

A menos que você tenha uma boa razão para usar o índice, Postgres pode estar fazendo a escolha correta. Por quê?

  • Para pequenas mesas, é mais rápido para fazer varreduras seqüenciais.
  • O Postgres não usar índices quando tipos de dados não correspondem corretamente, você pode necessitar de incluir moldes apropriados.
  • Suas configurações planejador pode estar causando problemas.

Veja também este post newsgroup de idade .

Respondeu 21/11/2008 em 20:04
fonte usuário

votos
0

produto PostgresPlus Advanced Server da EnterpriseDB suporta o Oracle sugere sintaxe, no entanto, que o produto não é livre.

Respondeu 09/07/2009 em 18:18
fonte usuário

votos
10

A questão em si é muito inválido. Forçando (fazendo enable_seqscan = off por exemplo) é muito má ideia. Pode ser útil para verificar se ele será mais rápido, mas o código de produção nunca deve usar esses truques.

Em vez disso - não explicar analisar de sua consulta, lê-lo, e descobrir por que PostgreSQL escolhe ruim (na sua opinião) plano.

Existem ferramentas na web que ajudam com a leitura explicar analisar saída - um deles é explain.depesz.com - escrito por mim.

Outra opção é entrar no canal #postgresql na freenode rede de IRC, e conversando com caras lá para ajudá-lo - como a otimização de consulta não é uma questão de "fazer uma pergunta, obter resposta ser feliz". é mais como uma conversa, com muitas coisas para verificar, muitas coisas a serem aprendidas.

Respondeu 09/07/2009 em 18:58
fonte usuário

votos
47

Provavelmente a única razão válida para usar

set enable_seqscan=false

é quando você está escrevendo consultas e quer ver rapidamente o que o plano de consulta seria realmente estavam lá grandes quantidades de dados na tabela (s). Ou, claro, se você precisa confirmar rapidamente que sua consulta não está usando um índice simplesmente porque o conjunto de dados é muito pequeno.

Respondeu 16/11/2012 em 02:33
fonte usuário

votos
8

Às vezes PostgreSQL não consegue fazer a melhor escolha de índices para uma determinada condição. Como exemplo, suponha que há uma mesa transações com vários milhões de linhas, dos quais há várias centenas para um determinado dia, ea tabela tem quatro índices: transaction_id, client_id, data e descrição. Você deseja executar a seguinte consulta:

SELECT client_id, SUM(amount)
FROM transactions
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND
      description = 'Refund'
GROUP BY client_id

PostgreSQL pode optar por utilizar o transactions_description_idx índice em vez de transactions_date_idx, o que pode levar à consulta tendo vários minutos, em vez de menos de um segundo. Se este for o caso, você pode forçar usando o índice na data em falsificando a condição como esta:

SELECT client_id, SUM(amount)
FROM transactions
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND
      description||'' = 'Refund'
GROUP BY client_id
Respondeu 16/06/2015 em 05:17
fonte usuário

votos
0

Há um carrapato para empurrar postgres preferir uma seqscan adicionando um OFFSET 0na subconsulta

Isso é útil para otimizar solicitações que ligam grandes enormes mesas / quando você está realmente procurando apenas o n punho / últimos elementos.

Vamos dizer que você está procurando primeiras / últimas 20 elementos que envolvem várias tabelas com 100k (ou mais) entradas, nenhum edifício Ponto / ligando-se tudo a consulta sobre todos os dados quando o que você estará procurando no primeiro 100 ou 1000 entradas. Neste cenário, por exemplo, ele acaba por ser mais de 10x mais rápido para fazer uma varredura sequencial.

veja Como posso evitar Postgres de inlining uma subconsulta?

Respondeu 26/10/2017 em 21:26
fonte usuário

votos
3

Resposta curta

Este problema geralmente acontece quando o custo estimado de uma varredura de índice é muito alto e não reflete corretamente a realidade. Pode ser necessário diminuir o random_page_costparâmetro de configuração para corrigir isso. A partir da documentação do PostgreSQL :

Reduzindo este valor [...] fará com que o sistema a preferir varreduras de índice; levantando ele vai fazer varreduras de índice parecer relativamente mais caros.

Você pode verificar se um valor mais baixo vai realmente fazer Postgres usar o índice (mas usar isso para testar única ):

EXPLAIN <query>;              # Uses sequential scan
SET random_page_cost = 1;
EXPLAIN <query>;              # May use index scan now

Você pode restaurar o valor padrão com SET random_page_cost = DEFAULT;novamente.

fundo

Varreduras de índice exigem buscas página disco não-seqüenciais. Postgres utiliza random_page_costpara estimar o custo de tais buscas não sequenciais em relação a buscas sequenciais. O valor por defeito é 4.0, assumindo assim uma média factor de custo de 4 em comparação com buscas sequenciais (tendo em conta os efeitos de armazenamento em cache).

O problema, porém, é que esse valor padrão é inadequado nos seguintes importantes cenários da vida real:

1) unidades de estado sólido

Armazenamento que tem um parente custo de leitura aleatória de baixo para seqüencial, por exemplo, unidades de estado sólido, pode ser mais bem modelado com um valor menor para random_page_cost.

De acordo com este slide de um fale a PostgresConf 2018, random_page_costdeve ser definido como 2.0ou inferior para unidades de estado sólido.

2) cache de dados Fortemente

Do mesmo modo, se os seus dados é provável que seja totalmente em cache, [...] diminuição random_page_costpode ser apropriado.

Se você sabe que o índice está totalmente em cache para a RAM (você também pode querer usar o pg_prewarm extensão para isso), random_page_costdeve mesmo ser ajustado para 1.0.


Respondeu 16/10/2018 em 10:31
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more