hash_join_cardinality optimizer_switch flag
In MySQL and MariaDB, the output cardinality of a part of query has been historically tied to the used access method(s). This is different from the approach used in database textbooks (there, the cardinality "x JOIN y" is the same regardless of which access methods are used to compute it).
Example
Consider a query joining customers with their orders:
select * from customer, orders, ... where customer.id = orders.customer_id and ...
Suppose, table orders has an index IDX
on orders.customer_id
.
If the query plan is using this index to fetch orders for each customer, the optimizer will use index statistics from IDX
to estimate the number of rows in the customer-joined-with-orders.
On the other hand, if the optimizer considers a query plan that joins customer with orders without use of indexes, it will ignore the customer.id = orders.customer_id
equality completely and will compute the
output cardinality as if customer was cross-joined with orders.
Hash join
MariaDB supports Block Hash Join. It is not enabled by default, one needs to set it join_cache_level to at least 3 to enable it.
Before MDEV-30812, Query optimization for Block Hash Join would work as described in the above example: It would assume that the join operation is a cross join.
MDEV-30812 introduces a new optimizer_switch flag, hash_join_cardinality
. In MariaDB versions before 11.0, it is off by default.
If one sets it to ON, the optimizer will make use of column histograms when computing the cardinality of hash join operation output.
One can see the computation in the Optimizer Trace, search for hash_join_cardinality
.