Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle 10g Connect By Prior - Problemas de Desempenho


Tentei recriar sua situação e não consegui que o Oracle usasse os índices com sabedoria. Tenho certeza de que há alguma maneira inteligente de fazer isso. Mas se ninguém mais aqui pode descobrir, abaixo está a maneira burra e feia.

Como você está obtendo apenas um certo número de níveis, pode criar manualmente uma conexão. Obter o primeiro nível, unir isso ao segundo nível (que obtém resultados de uma cópia da primeira consulta), unir isso ao terceiro nível (que obtém resultados de uma cópia da segunda consulta), etc. Eu fiz apenas três níveis aqui, mas você pode copiar e colar para fazer o quarto. É mais difícil de usar, pois o id original é repetido tantas vezes, mas é super rápido (0,005 segundos na minha máquina com 1,6 milhão de registros).
--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')
);