Próbowałem odtworzyć twoją sytuację i nie byłem w stanie skłonić Oracle do mądrego wykorzystania indeksów. Jestem pewien, że jest na to jakiś sprytny sposób. Ale jeśli nikt inny tutaj nie może tego rozgryźć, poniżej jest głupi, brzydki sposób.
Ponieważ otrzymujesz tylko określoną liczbę poziomów, możesz ręcznie utworzyć połączenie. Uzyskaj pierwszy poziom, połączenie tego z drugim poziomem (który otrzymuje wyniki z kopii pierwszego zapytania), połączenie tego z trzecim poziomem (który otrzymuje wyniki z kopii drugiego zapytania) itd. Zrobiłem tylko trzy poziomy tutaj, ale możesz skopiować i wkleić, aby utworzyć czwartą. Jest to trudniejsze w użyciu, ponieważ oryginalny identyfikator jest powtarzany tyle razy, ale jest super szybki (0,005 sekundy na moim komputerze z 1,6 milionami rekordów).
--Original animal
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 0 "level" from animals where animal_id = '101'
union all
--Parents
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 1 "level" from animals
where animal_id = (select sire_animal_id from animals where animal_id = '101')
union all
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 1 "level" from animals
where animal_id = (select dam_animal_id from animals where animal_id = '101')
union all
--Grand parents
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 2 "level" from animals
where animal_id =
(
select sire_animal_id from animals
where animal_id = (select sire_animal_id from animals where animal_id = '101')
)
union all
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 2 "level" from animals
where animal_id =
(
select dam_animal_id from animals
where animal_id = (select sire_animal_id from animals where animal_id = '101')
)
union all
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 2 "level" from animals
where animal_id =
(
select sire_animal_id from animals
where animal_id = (select dam_animal_id from animals where animal_id = '101')
)
union all
select '101' original_animal, animal_id, line_id, sire_animal_id, dam_animal_id, 2 "level" from animals
where animal_id =
(
select dam_animal_id from animals
where animal_id = (select dam_animal_id from animals where animal_id = '101')
);