Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle 10g Connect By Prior - Problemi di prestazioni

Ho provato a ricreare la tua situazione e non sono riuscito a convincere Oracle a utilizzare saggiamente gli indici. Sono sicuro che c'è un modo intelligente per farlo. Ma se nessun altro qui riesce a capirlo, di seguito c'è il modo stupido e brutto.

Dal momento che stai ottenendo solo un certo numero di livelli, puoi creare manualmente una connessione tramite. Ottieni il primo livello, uniscilo al secondo livello (che ottiene i risultati da una copia della prima query), uniscilo al terzo livello (che ottiene i risultati da una copia della seconda query), ecc. Ho fatto solo tre livelli qui, ma puoi copiare e incollare per fare il quarto. È più difficile da usare poiché l'ID originale viene ripetuto così tante volte, ma è super veloce (0,005 secondi sulla mia macchina con 1,6 milioni di record.)

--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')
);