sql >> Database >  >> RDS >> PostgreSQL

Postgres NIET IN uitvoering

Een enorme IN lijst is erg inefficiënt. PostgreSQL zou het idealiter moeten identificeren en veranderen in een relatie waarop het een anti-join doet, maar op dit moment weet de queryplanner niet hoe dat moet, en de planningstijd die nodig is om dit geval te identificeren, zou elke query kosten die gebruikt NOT IN verstandig, dus het zou een zeer goedkope controle moeten zijn. Zie dit eerdere veel gedetailleerdere antwoord over het onderwerp .

Zoals David Aldridge schreef, kan dit het beste worden opgelost door er een anti-join van te maken. Ik zou het schrijven als een join over een VALUES lijst simpelweg omdat PostgreSQL extreem snel is in het ontleden van VALUES lijsten in relaties op, maar het effect is hetzelfde:

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; 

Voor een voldoende grote set waarden kunt u zelfs beter een tijdelijke tabel maken, COPY de waarden erin in te voeren, een PRIMARY KEY . aan te maken erop, en daaraan meedoen.

Meer mogelijkheden onderzocht hier:

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



  1. Welk gegevenstype moet worden gebruikt voor het gehashte wachtwoordveld en welke lengte?

  2. dubbele vermeldingen mysql en php

  3. PL/SQL-procedure:Hoe een select-statement retourneren?

  4. IW en MM gebruiken in Oracle