A method of joining data records using a computer, the method comprising: identifying data records in a first data stream (300, 300a) and data records in a second data stream (300, 300b); computing a hash for each data record in the first and second data streams; assigning data records in the first data stream to a plurality of first groups based on the computed hashes of the data records in the first data stream, wherein the data records in the first data stream are assigned to each first group based on a set number of least significant bits of the computed hashes of the data records in the first data stream; assigning data records in the second data stream to a plurality of second groups based on the computed hashes of the data records in the second data stream, wherein the data records in the second data stream are assigned to each second group based on a set number of LSBs of the computed hashes of the data records in the second data stream, wherein a number of the plurality of first groups and a number of the plurality of second groups is dependent on a number of worker threads available to process the join operation and/or a number of processor cores of the computer, wherein the set number of LSBs of the computed hashes of the data records in the first data stream is the same as the set number of LSBs of the computed hashes of the data records in the second data stream, wherein the set number of LSBs of the computed hashes of the data records in the first data stream and the set number of LSBs of the computed hashes of the data records in the second data stream is determined based on the number of the plurality of first groups and a number of the plurality of second groups; for each first group of the plurality of first groups, assigning the first group of the plurality of first groups and a corresponding second group of the plurality of second groups to a worker thread of a plurality of worker threads, wherein a first group and a second group assigned to a same worker thread are associated with a same set of LSBs; determining, by the worker thread based on the computed hashes of the data records in the first and second groups (311-313, 314-316) assigned to the worker thread, whether to join data records in the first group with data records in the second group; responsive to determining to join one or more data records of the first group with one or more data records in the second group, joining, by the worker thread, the one or more data records of the first group with the one or more data records in the second group; and outputting, by the worker thread, the joined data records. identifying data records in a first data stream (300, 300a) and data records in a second data stream (300, 300b); computing a hash for each data record in the first and second data streams; assigning data records in the first data stream to a plurality of first groups based on the computed hashes of the data records in the first data stream, wherein the data records in the first data stream are assigned to each first group based on a set number of least significant bits of the computed hashes of the data records in the first data stream; assigning data records in the second data stream to a plurality of second groups based on the computed hashes of the data records in the second data stream, wherein the data records in the second data stream are assigned to each second group based on a set number of LSBs of the computed hashes of the data records in the second data stream, wherein a number of the plurality of first groups and a number of the plurality of second groups is dependent on a number of worker threads available to process the join operation and/or a number of processor cores of the computer, wherein the set number of LSBs of the computed hashes of the data records in the first data stream is the same as the set number of LSBs of the computed hashes of the data records in the second data stream, wherein the set number of LSBs of the computed hashes of the data records in the first data stream and the set number of LSBs of the computed hashes of the data records in the second data stream is determined based on the number of the plurality of first groups and a number of the plurality of second groups; for each first group of the plurality of first groups, assigning the first group of the plurality of first groups and a corresponding second group of the plurality of second groups to a worker thread of a plurality of worker threads, wherein a first group and a second group assigned to a same worker thread are associated with a same set of LSBs; determining, by the worker thread based on the computed hashes of the data records in the first and second groups (311-313, 314-316) assigned to the worker thread, whether to join data records in the first group with data records in the second group; responsive to determining to join one or more data records of the first group with one or more data records in the second group, joining, by the worker thread, the one or more data records of the first group with the one or more data records in the second group; and outputting, by the worker thread, the joined data records.