私はあなたの状況を再現しようとしましたが、Oracle にインデックスを賢く使用させることができませんでした。きっと何か賢い方法があると思います。しかし、ここで誰もそれを理解できない場合は、以下の愚かで醜い方法があります.
特定の数のレベルしか取得していないため、手動で接続を作成できます。最初のレベルを取得し、それを 2 番目のレベル (最初のクエリのコピーから結果を取得する) に結合し、それを 3 番目のレベル (2 番目のクエリのコピーから結果を取得) に結合します。ここにコピーして貼り付けて 4 番目を作成できます。元の ID が何度も繰り返されるので使いにくいですが、非常に高速です (私のマシンでは 160 万レコードで 0.005 秒です)。
--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')
);