An update: I spent the day reading-about/playing-with hashes, and decided to use them to the problem I had.
Satisfied with the results I now have at a constant 20% single-core utilization (approx), and a peak 1.5GB memory footprint.
Distinct products: 2083
Number of pairs (incl. duplicates): 4,336,806
Number of pairs (excl. duplicates): 2,168,403
Started processing at 14:04:49
Finished processing at 14:07:24
Finished writing to disk at 14:07:43
PS: This is to determine the pairs only (haven't run the stats using the pairs yet which is the next step).