Conozco al menos una optimización que podría reducir el tiempo de ejecución a la mitad:
AND a.id < b.id
Esto le impide probar a=1, b=2 cuando ya ha probado a=2, b=1.
Sin embargo, seguirá siendo O(n^2), pero no veo cómo puedes hacer mucho al respecto.