Опитах се да пресъздам вашата ситуация и не успях да накарам Oracle да използва индексите разумно. Сигурен съм, че има някакъв умен начин да го направим. Но ако никой друг тук не може да го разбере, по-долу е тъпият, грозен начин.
Тъй като получавате само определен брой нива, можете ръчно да създадете връзка. Вземете първото ниво, обединете това към второто ниво (което получава резултати от копие на първата заявка), обединете това към третото ниво (което получава резултати от копие на втората заявка) и т.н. Направих само три нива тук, но можете да копирате и поставите, за да направите четвъртия. По-трудно е да се използва, тъй като оригиналният идентификатор се повтаря толкова много пъти, но е супер бърз (0,005 секунди на моята машина с 1,6 милиона записа.)
--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')
);