Encontrei um cenário em que a mesma consulta em um banco de dados PostgreSQL exibe diferentes seleções de índice e estratégias de junção entre os ambientes QA e Prod. Estou tentando entender as possíveis razões por trás desse comportamento.
Aqui estão os detalhes:
Ambiente de controle de qualidade:
- Conjunto de dados menor em comparação com o Prod
- A consulta usa junção de loop aninhada
- Consulta usa
idx_user_id_id_customer_id
índice - Item de lista
Ambiente de produção:
- Conjunto de dados maior em comparação com o controle de qualidade
- A consulta usa junção de mesclagem
- Consulta usa
idx_customer_id
índice - O tamanho do
idx_user_id_customer_id
índice é de 118 GB, enquantoidx_customer_id
o índice é de 85 GB
Ambos os ambientes têm o mesmo conjunto de índices. As principais diferenças estão no tamanho dos dados e nos planos de execução escolhidos pelo otimizador de consultas.
Registro de explicação do produto: https://explain.depesz.com/s/28la
Registro de explicação do controle de qualidade: https://explain.depesz.com/s/zM6e
1. Quais seriam as possíveis razões para a disparidade na seleção de índices e na estratégia de junção entre os dois ambientes?
2. Existem fatores específicos que influenciam o processo de tomada de decisão do otimizador?
Aqui está o que eu penso, por favor me corrija se eu estiver errado e adicione mais informações:
- Ele está usando junção de loop aninhado em vez de junção de mesclagem porque no controle de qualidade pode haver menos linhas para o mesmo registro em um lado.
- O tamanho do índice
idx_user_id_customer_id
é grande, por isso está sendo ignorado. Ou pode ser que a seletividadeuser_id
seja baixa, porcustomer_id
isso está escolhendocustomer_id
Essa é a disparidade, os dados diferentes, principalmente a diferença na quantidade de linhas.
Sim, o tamanho dos dados. Diferentes operações de dados no plano de consulta são mais eficientes, dependendo do tamanho dos dados que estão sendo operados. Loops aninhados são normalmente mais eficientes para conjuntos menores de dados sendo unidos. Merge Join é melhor para conjuntos de dados maiores.
É difícil manter vários ambientes consistentes o suficiente para obter sempre os mesmos planos de consulta para todas as consultas, mas, para isso, você teria que manter um conjunto de dados bastante semelhante entre os ambientes, em todas as tabelas relevantes.