pony icon indicating copy to clipboard operation
pony copied to clipboard

Left join not correct worked in PostgreSQL

Open norguhtar opened this issue 4 years ago • 0 comments

I got really strange thing but it true

For example i'm put in code

left_join(a for a in Application for ac in a.catalogs if ac.tsto is None)

And got in sql

SELECT DISTINCT "a"."uid", "a"."name"
FROM "ext"."application" "a"
  LEFT INNER JOIN "ext"."application_catalog" "ac"
    ON "a"."uid" = "ac"."uid_application"
WHERE "ac"."tsto" IS NULL

But if i try run explain i got

explain SELECT DISTINCT "a"."uid", "a"."name"
FROM "ext"."application" "a"
  LEFT JOIN "ext"."application_catalog" "ac"
    ON "a"."uid" = "ac"."uid_application"
WHERE "ac"."tsto" IS NULL
;
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 Unique  (cost=55.25..55.29 rows=5 width=48)
   ->  Sort  (cost=55.25..55.27 rows=5 width=48)
         Sort Key: a.uid, a.name
         ->  Hash Right Join  (cost=34.08..55.20 rows=5 width=48)
               Hash Cond: (ac.uid_application = a.uid)
               Filter: (ac.tsto IS NULL)
               ->  Seq Scan on application_catalog ac  (cost=0.00..18.80 rows=880 width=24)
               ->  Hash  (cost=20.70..20.70 rows=1070 width=48)
                     ->  Seq Scan on application a  (cost=0.00..20.70 rows=1070 width=48)

Hey why right join in my query plan? Answer

https://stackoverflow.com/questions/24876673/explain-join-vs-left-join-and-where-condition-performance-suggestion-in-more-de/24876797#24876797

How fix that? Just change generated sql like this

explain SELECT DISTINCT "a"."uid", "a"."name"
FROM "ext"."application" "a"
  LEFT JOIN "ext"."application_catalog" "ac"
    ON "a"."uid" = "ac"."uid_application" AND "ac"."tsto" IS NULL;

                                     QUERY PLAN                                     
------------------------------------------------------------------------------------
 Hash Left Join  (cost=18.85..43.60 rows=1070 width=112)
   Hash Cond: (a.uid = ac.uid_application)
   ->  Seq Scan on application a  (cost=0.00..20.70 rows=1070 width=48)
   ->  Hash  (cost=18.80..18.80 rows=4 width=64)
         ->  Seq Scan on application_catalog ac  (cost=0.00..18.80 rows=4 width=64)
               Filter: (tsto IS NULL)

And you can see it worked as expected

norguhtar avatar Feb 24 '21 18:02 norguhtar