Tôi đã thử tạo lại tình huống của bạn và tôi không thể khiến Oracle sử dụng các chỉ mục một cách khôn ngoan. Tôi chắc rằng có một số cách thông minh để làm điều đó. Nhưng nếu không ai khác ở đây có thể tìm ra điều đó, thì dưới đây là cách ngu ngốc, xấu xí.
Vì bạn chỉ nhận được một số cấp độ nhất định, bạn có thể tạo kết nối theo cách thủ công. Lấy cấp độ đầu tiên, liên kết cấp độ đó với cấp độ thứ hai (nhận kết quả từ bản sao của truy vấn đầu tiên), kết hợp cấp độ đó với cấp độ thứ ba (cấp kết quả từ bản sao của truy vấn thứ hai), v.v. Tôi chỉ thực hiện ba cấp độ ở đây, nhưng bạn có thể sao chép và dán để tạo thành thứ tư. Khó sử dụng hơn vì id gốc được lặp lại rất nhiều lần, nhưng nó rất nhanh (0,005 giây trên máy của tôi với 1,6 triệu bản ghi.)
--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')
);