Я попытался воссоздать вашу ситуацию, и я не смог заставить 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')
);
Что такое план выполнения? Какие индексы существуют на столе? –
Возможно, у вас есть это ИЛИ в соединении (смешивая два дерева в одной структуре), вы пробовали объединение двух отдельных запросов (один для дерева сир, второй для дерева дам)? – kurosch