IME, MySQL nie radzi sobie dobrze z optymalizacją podzapytań - szczególnie wydaje się, że nie zarządza predykatami push.
Jestem trochę zdezorientowany co do tego, co zapytanie ma faktycznie zwrócić - szczególnie „podrzędny rodzic”
Uzyskasz pewną poprawę, umieszczając left_id i right_id w jednym indeksie.
Chociaż można również uzyskać pewną poprawę poprzez rozwinięcie zapytania do procedury składowanej, biorąc pod uwagę, że za każdym razem wydaje się, że przemierzasz prawie cały zestaw danych, lepszym rozwiązaniem jest denormalizacja głębokości drzewa i przechowywanie jej jako atrybutu dla każdego węzła. Rzeczywiście wydaje się, że przechodzisz to co najmniej dwa razy w samym zewnętrznym zapytaniu.
Zauważyłem jednak, że na końcu zapytania:
HAVING depth > 0
AND depth <= 1
Co z pewnością jest tym samym, co
HAVING depth=1
Co z kolei zapewnia zupełnie inny sposób optymalizacji zapytania (zacznij od pobrania wszystkich węzłów, w których right=left+1, aby znaleźć węzły bez dzieci i przejdź dalej, aby sprawdzić identyfikator kategorii).