sql >> Base de Datos >  >> RDS >> PostgreSQL

Postgres NO EN rendimiento

Un enorme IN lista es muy ineficiente. Idealmente, PostgreSQL debería identificarlo y convertirlo en una relación en la que no se une, pero en este punto el planificador de consultas no sabe cómo hacerlo, y el tiempo de planificación requerido para identificar este caso costaría cada consulta que usa NOT IN con sensatez, por lo que tendría que ser un cheque de muy bajo costo. Consulte esta respuesta anterior mucho más detallada sobre el tema .

Como escribió David Aldridge, esto se resuelve mejor convirtiéndolo en un anti-join. Lo escribiría como una unión sobre un VALUES list simplemente porque PostgreSQL es extremadamente rápido para analizar VALUES listas en relaciones, pero el efecto es el mismo:

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 un conjunto de valores lo suficientemente grande, incluso podría ser mejor crear una tabla temporal, COPY ing los valores en él, creando una PRIMARY KEY en él, y unirse a eso.

Más posibilidades exploradas aquí:

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