IME, MySQL si nevede dobře při optimalizaci dílčích dotazů – zvláště se zdá, že nezvládá push-predikáty.
Jsem trochu zmatený tím, co má dotaz ve skutečnosti vracet – zejména „podřazený“
Určitého zlepšení byste dosáhli vložením left_id a right_id do jednoho indexu.
I když také získáte určité zlepšení rozbalením dotazu do uložené procedury, vzhledem k tomu, že se zdá, že pokaždé procházíte téměř celou datovou sadou, lepším řešením by bylo denormalizovat hloubku stromu a uložit ji jako atribut pro každý uzel. Skutečně se zdá, že jej procházíte alespoň dvakrát pouze ve vnějším dotazu.
Všiml jsem si však, že na konci dotazu:
HAVING depth > 0
AND depth <= 1
Což je jistě totéž jako
HAVING depth=1
Což pak poskytuje velmi odlišný způsob optimalizace dotazu (začněte získáním všech uzlů, kde right=left+1, abyste našli uzly bez potomků, a vypracujte způsob, jak zkontrolovat id kategorie).