sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres INTE I prestanda

En enorm IN listan är mycket ineffektiv. PostgreSQL borde idealiskt identifiera det och förvandla det till en relation som det gör en anti-join på, men vid det här laget vet frågeplaneraren inte hur man gör det, och den planeringstid som krävs för att identifiera detta fall skulle kosta varje fråga som använder NOT IN förnuftigt, så det måste vara en mycket låg kostnadskontroll. Se det här tidigare mycket mer detaljerade svaret om ämnet .

Som David Aldridge skrev löses detta bäst genom att förvandla det till en anti-join. Jag skulle skriva det som en sammanfogning över en VALUES lista helt enkelt för att PostgreSQL är extremt snabb på att analysera VALUES listar i relationer, men effekten är densamma:

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; 

För en tillräckligt stor uppsättning värden kan det till och med vara bättre att skapa en tillfällig tabell, COPY lägga in värdena i den och skapa en PRIMARY KEY på den, och gå med på det.

Fler möjligheter utforskas här:

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



  1. Hur ställer jag in en anslutningssträng för en MySQL-databas i ett C#-projekt utan att använda dialogrutor?

  2. Hur UNHEX()-funktionen fungerar i MySQL

  3. Hur man konfigurerar Source-Replica Replication i MySQL

  4. Registrerar UNIX tidszon?