sql >> Databáze >  >> RDS >> PostgreSQL

Postgres NENÍ VE VÝKONU

Obrovský IN seznam je velmi neefektivní. PostgreSQL by jej měl ideálně identifikovat a převést na relaci, u které provede anti-join, ale v tomto okamžiku plánovač dotazů neví, jak to udělat, a čas plánování potřebný k identifikaci tohoto případu by stál každý dotaz, který používá NOT IN rozumně, takže by to musela být kontrola s velmi nízkými náklady. Viz tuto dřívější mnohem podrobnější odpověď na toto téma .

Jak napsal David Aldridge, toto se nejlépe vyřeší tak, že se to změní na anti-join. Napsal bych to jako spojení přes VALUES seznam jednoduše proto, že PostgreSQL je extrémně rychlý při analýze VALUES uvádí do vztahů, ale efekt je stejný:

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; 

Pro dostatečně velkou sadu hodnot může být dokonce lepší vytvořit dočasnou tabulku COPY vložením hodnot do něj vytvoříte PRIMARY KEY na to a připojit se k tomu.

Další možnosti prozkoumány zde:

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



  1. mysql odborová otázka

  2. Získejte horní řádek po objednávce v Oracle Subquery

  3. Najít přidružení mezi databázovými poštovními účty a principy databáze v SQL Server (T-SQL)

  4. Jak iterovat hodnoty pole jsonb PostgreSQL pro účely porovnávání v rámci dotazu