Je connais au moins une optimisation qui pourrait réduire de moitié le temps d'exécution :
AND a.id < b.id
Cela vous évite de tester a=1, b=2 alors que vous avez déjà testé a=2, b=1.
Ça va toujours être O(n^2) cependant, mais je ne vois pas comment vous pouvez faire grand-chose à ce sujet.