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

Explicar a sugestão de desempenho da condição JOIN vs. LEFT JOIN e WHERE com mais detalhes


Efetivamente, WHERE condições e JOIN condições para [INNER] JOIN são 100% equivalentes no PostgreSQL. (É uma boa prática usar JOIN explícito condições para tornar as consultas mais fáceis de ler e manter).

O mesmo não true para um LEFT JOIN combinado com um WHERE condição em uma tabela à direita da junção. A finalidade de um LEFT JOIN é preservar todas as linhas do lado esquerdo da junção, independentemente de uma correspondência no lado direito. Se nenhuma correspondência for encontrada, a linha será estendida com NULL valores para colunas no lado direito. O manual:

LEFT OUTER JOIN

Primeiro, uma junção interna é executada. Então, para cada linha em T1 que não satisfaça a condição de junção com nenhuma linha em T2, uma linha unida é adicionada com valores nulos nas colunas de T2. Assim, a tabela unida sempre tem pelo menos uma linha para cada linha em T1.

Se você aplicar um WHERE condição que requer algo além de um NULL valor nas colunas das tabelas do lado direito, você anula o efeito e força a conversão do LEFT [OUTER] JOIN para funcionar como um simples [INNER] JOIN , apenas (possivelmente) mais caro devido a um plano de consulta mais complicado.

Em uma consulta com muitas tabelas unidas, o Postgres (ou qualquer RDBMS) é difícil encontrar o melhor (ou mesmo um bom) plano de consulta. O número de sequências teoricamente possíveis para unir tabelas cresce fatorialmente (!). O Postgres usa o "Generic Query Optimizer" para a tarefa e existem algumas configurações para influenciá-lo.

Ofuscando a consulta com LEFT JOIN enganoso conforme descrito, torna o trabalho do planejador de consulta mais difícil, é enganoso para leitores humanos e normalmente sugere erros na lógica de consulta.

Respostas relacionadas para problemas decorrentes disso:
  • Por que null é igual a inteiro em WHERE?
  • Consulta com LEFT JOIN não retornando linhas para contagem de 0
  • Consulta SQL usando junção externa e limitando registros filho para cada pai
  • Junta externa esquerda agindo como união interna
  • Selecione as linhas que não estão presentes em outra tabela

etc.