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

Postgres NÃO está em desempenho


Um enorme IN lista é muito ineficiente. Idealmente, o PostgreSQL deve identificá-lo e transformá-lo em uma relação na qual faça um anti-join, mas neste ponto o planejador de consultas não sabe como fazer isso, e o tempo de planejamento necessário para identificar esse caso custaria cada consulta que usa NOT IN sensatamente, então teria que ser uma verificação de custo muito baixo. Veja esta resposta anterior muito mais detalhada sobre o tópico .

Como David Aldridge escreveu, isso é melhor resolvido transformando-o em um anti-join. Eu escreveria como uma junção sobre um VALUES list simplesmente porque o PostgreSQL é extremamente rápido em analisar VALUES listas em relações, mas o efeito é o mesmo:
SELECT entityid 
FROM entity e
LEFT JOIN level1entity l1 ON l.level1id = e.level1_level1id
LEFT JOIN level2entity l2 ON l2.level2id = l1.level2_level2id
LEFT OUTER JOIN (
    VALUES
    (1377776),(1377792),(1377793),(1377794),(1377795),(1377796)
) ex(ex_entityid) ON (entityid = ex_entityid)
WHERE l2.userid = 'a987c246-65e5-48f6-9d2d-a7bcb6284c8f' 
AND ex_entityid IS NULL; 

Para um conjunto de valores suficientemente grande, talvez seja melhor criar uma tabela temporária, COPY inserindo os valores nele, criando uma PRIMARY KEY nele, e juntar-se a isso.

Mais possibilidades exploradas aqui:

https://stackoverflow.com/a/17038097/398670