Saya tahu setidaknya satu pengoptimalan yang dapat memotong waktu berjalan menjadi dua:
AND a.id < b.id
Ini mencegah Anda menguji a=1, b=2 saat Anda telah menguji a=2, b=1.
Ini masih akan menjadi O(n^2), tapi saya tidak bisa melihat bagaimana Anda bisa berbuat banyak tentang itu.