Here is a real life example using the "type" solution :
SELECT *
FROM BinDescription b
JOIN RobotDescription r
ON b.physicalContainerType = 'ROBOT'
AND b.physicalContainerFK = r.robotPK
JOIN RobotMissionDescription rm
ON rm.robotFK = r.robotPK
;
Which gives me this plan :
Merge Join (cost=225.12..395.31 rows=12026 width=301) (actual time=4.372..67.206 rows=47293 loops=1)
Merge Cond: (b.physicalcontainerfk = r.robotpk)
-> Nested Loop (cost=222.91..15184.24 rows=88 width=152) (actual time=4.321..44.448 rows=47293 loops=1)
-> Index Scan using bindescription_physicalcontainertype_physicalcontainerfk_key on bindescription b (cost=0.29..13.66 rows=4 width=76) (actual time=0.011..0.017 rows=4 loops=1)
Index Cond: (physicalcontainertype = 'ROBOT'::physicalcontainertype)
-> Bitmap Heap Scan on robotmissiondescription rm (cost=222.62..3672.39 rows=12026 width=76) (actual time=2.431..7.985 rows=11823 loops=4)
Recheck Cond: (robotfk = b.physicalcontainerfk)
Heap Blocks: exact=14246
-> Bitmap Index Scan on idx_robotmissiondescription_robotfk (cost=0.00..219.62 rows=12026 width=0) (actual time=1.629..1.629 rows=11823 loops=4)
Index Cond: (robotfk = b.physicalcontainerfk)
-> Sort (cost=2.20..2.29 rows=34 width=149) (actual time=0.044..4.752 rows=47321 loops=1)
Sort Key: r.robotpk
Sort Method: quicksort Memory: 34kB
-> Seq Scan on robotdescription r (cost=0.00..1.34 rows=34 width=149) (actual time=0.007..0.014 rows=34 loops=1)
Planning time: 1.559 ms
Execution time: 69.480 ms