Simplified test case:
select count(*)
from employee e1
left join employee e2 on e1.emp_no = e2.emp_no
left join employee e3 on e2.emp_no = e3.emp_no
left join employee e4 on e3.emp_no = e4.emp_no
left join employee e5 on e4.emp_no = e5.emp_no
where e1.salary > 0;
Predicate in the WHERE clause is pushed into the join stack and applied to the E1 data source which is correct. However, it still remains at the upper level and applied again. Prior to v5.0, it was redundantly applied only once, at the top-most level, see Filter in the plan marked with an asterisk:
Select Expression
-> Aggregate
* -> Filter
-> Nested Loop Join (outer)
-> Nested Loop Join (outer)
-> Nested Loop Join (outer)
-> Nested Loop Join (outer)
-> Filter
-> Table "EMPLOYEE" as "E1" Full Scan
-> Filter
-> Table "EMPLOYEE" as "E2" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E3" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E4" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E5" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
However, after #3218, Firebird 5.0 redundantly evaluates this predicate at the every join level, see:
Select Expression
-> Aggregate
* -> Filter
-> Nested Loop Join (outer)
* -> Filter
-> Nested Loop Join (outer)
* -> Filter
-> Nested Loop Join (outer)
* -> Filter
-> Nested Loop Join (outer)
-> Filter
-> Table "EMPLOYEE" as "E1" Full Scan
-> Filter
-> Table "EMPLOYEE" as "E2" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E3" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E4" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
-> Filter
-> Table "EMPLOYEE" as "E5" Access By ID
-> Bitmap
-> Index "RDB$PRIMARY7" Unique Scan
thus negatively affecting the query performance.
Simplified test case:
Predicate in the
WHEREclause is pushed into the join stack and applied to theE1data source which is correct. However, it still remains at the upper level and applied again. Prior to v5.0, it was redundantly applied only once, at the top-most level, seeFilterin the plan marked with an asterisk:However, after #3218, Firebird 5.0 redundantly evaluates this predicate at the every join level, see:
thus negatively affecting the query performance.