Skip to content

Disabling Join Elimination for LEFT Joins

Join elimination is a query optimization that can occur during planning when primary and foreign keys exist on the tables. The query plan may eliminate redundant joins when these key relationships have been declared. However, because Yellowbrick does not enforce primary key and foreign key constraints, your tables may have key relationships that are not valid. If this is true, the elimination of joins between those tables may cause queries to return wrong results.

To prevent this problem from occurring specifically for LEFT OUTER joins, you can set the enable_join_elimination configuration parameter to OFF. This parameter defaults to ON. Note that changing this parameter to OFF does not influence the planning of other joins, such as INNER joins.

For example, consider the primary and foreign key constraints for the following tables:

yellowbrick=# \d match
               Table "public.match"
  Column  |            Type             | Modifiers 
----------+-----------------------------+-----------
 seasonid | smallint                    | not null
 matchday | timestamp without time zone | 
 htid     | smallint                    | 
 atid     | smallint                    | 
 ftscore  | character(3)                | 
 htscore  | character(3)                | 

Distribution: Hash (seasonid)
Columns:
   seasonid PRIMARY KEY
Foreign-key constraints:
   "season_fk" FOREIGN KEY (seasonid) REFERENCES season(seasonid)
Primary-key constraints:
   "match_pk" PRIMARY KEY (seasonid)

yellowbrick=# \d season
             Table "public.season"
   Column    |         Type          | Modifiers 
-------------+-----------------------+-----------
 seasonid    | smallint              | 
 season_name | character(9)          | 
 numteams    | smallint              | 
 winners     | character varying(30) | 

Distribution: Hash (seasonid)
Columns:
   seasonid UNIQUE
Unique constraints:
   "season_seasonid_key" UNIQUE (seasonid)
Referenced by:
   TABLE "match" CONSTRAINT "season_fk" FOREIGN KEY (seasonid) REFERENCES season(seasonid)

By default, the following LEFT OUTER join of these tables eliminates the join from the query plan:

yellowbrick=# show enable_join_elimination;
 enable_join_elimination 
-------------------------
 on
(1 row)
yellowbrick=# explain select m.* from match m left join season s on m.seasonid=s.seasonid;
                   QUERY PLAN                    
--------------------------------------------------
 id   rows_planned   workers   node   
  1           8606       all   SELECT   
  3           8606       all   SCAN match AS m   
 Database: yellowbrick
 Version: 5.2.9-20211208203120
 Hostname: yb007-mgr1.mvw.yellowbrick.io
 
(7 rows)

When you set enable_join_elimination to OFF, the plan changes:

yellowbrick=# set enable_join_elimination to off;
SET
yellowbrick=# explain select m.* from match m left join season s on m.seasonid=s.seasonid;
                                    QUERY PLAN                                     
------------------------------------------------------------------------------------
 id   rows_planned   workers   node   
  1           8606       all   SELECT   
  9           8606       all   LEFT OUTER HASH JOIN ON (s.seasonid = m.seasonid)   
 12           8606       all   |-SCAN match AS m   
  2             25       all   |-BUILD   
  5             25       all     SCAN season AS s   
 Database: yellowbrick
 Version: 5.2.9-20211208203120
 Hostname: yb007-mgr1.mvw.yellowbrick.io
 
(10 rows)

Here is another example with the same two tables:

yellowbrick=# show enable_join_elimination;
 enable_join_elimination 
-------------------------
 on
(1 row)
yellowbrick=# explain select distinct(m.seasonid) from match m left join season s on m.seasonid=s.seasonid;
                      QUERY PLAN                       
--------------------------------------------------------
 id   rows_planned   workers   node   
  1           8606       all   SELECT   
  3           8606       all   GROUP BY (m.seasonid)   
  6           8606       all   SCAN match AS m   
 Database: yellowbrick
 Version: 5.2.9-20211208203120
 Hostname: yb06-mgr1.slc.yellowbrick.io
 
(8 rows)

yellowbrick=# set enable_join_elimination to off;
SET
yellowbrick=# explain select distinct(m.seasonid) from match m left join season s on m.seasonid=s.seasonid;
                                    QUERY PLAN                                     
------------------------------------------------------------------------------------
 id   rows_planned   workers   node   
  1           8606       all   SELECT   
  3           8606       all   GROUP BY (m.seasonid)   
 11           8606       all   LEFT OUTER HASH JOIN ON (s.seasonid = m.seasonid)   
 14           8606       all   |-SCAN match AS m   
  4             25       all   |-BUILD   
  7             25       all     SCAN season AS s   
 Database: yellowbrick
 Version: 5.2.9-20211208203120
 Hostname: yb06-mgr1.slc.yellowbrick.io
 
(11 rows)

Parent topic:CREATE TABLE