This algorithm is simple, but it requires that the smaller join relation fits into memory, which is sometimes not the case.
A simple approach to handling this situation proceeds as follows: This is essentially the same as the block nested loop join algorithm.
The algorithm then loads pairs of partitions into memory, builds a hash table for the smaller partitioned relation, and probes the other relation for matches with the current hash table.
It is possible that one or more of the partitions still does not fit into the available memory, in which case the algorithm is recursively applied: an additional orthogonal hash function is chosen to hash the large partition into sub-partitions, which are then processed as before.
It uses minimal amount of memory for partitioning like in grace hash join and uses the remaining memory to initialize a classical hash join during partitioning phase.
During the partitioning phase, the hybrid hash join uses the available memory for two purposes: Because partition 0 is never written to disk, hybrid hash join typically performs fewer I/O operations than grace hash join.
Hash semi-join is used to return the records found in the other table.
As with the anti-join, semi-join can also be left and right: The records are returned right after they produced a hit.