Dlaczego Oracle SQL Optimizer ignoruje predykat indeksu dla tego widoku?

Usiłuję zoptymalizować zestaw przechowywanych proc, które działają przeciwko wielu tabelom, w tym tym widoku. Widok jest taki:

Mamy TBL_A (id, hist_date, hist_type, other_columns) z dwoma typami wierszy: hist_type 'O' vs. hist_type 'N'. Sam widok łączy tabelę A z sobą i transponuje N wierszy do odpowiednich wierszy O. Jeśli nie istnieje żaden wiersz N dla wiersza O, wartości wiersza O są powtarzane. Tak jak:

CREATE OR REPLACE FORCE VIEW V_A (id, hist_date, hist_type, other_columns_o, other_columns_n)
select 
o.id, o.hist_date, o.hist_type, 
o.other_columns as other_columns_o,
case when n.id is not null then n.other_columns else o.other_columns end as other_columns_n
from
TBL_A o left outer join TBL_A n
on o.id=n.id and o.hist_date=n.hist_date and n.hist_type = 'N'
where o.hist_type = 'O';

TBL_A ma unikalny indeks na: (id, hist_date, hist_type). Ma także unikalny indeks na: (hist_date, id, hist_type) i jest to klucz podstawowy.

Występuje następujące zapytanie (w zapisanym proc, z x zadeklarowanym jako TYPE_TABLE_OF_NUMBER):

select b.id BULK COLLECT into x from TBL_B b where b.parent_id = input_id;

select v.id from v_a v
where v.id in (select column_value from table(x))
and   v.hist_date = input_date
and   v.status_new = 'CLOSED';

To zapytanie ignoruje indeks w kolumnie id podczas uzyskiwania dostępu do TBL_A, a zamiast tego wykonuje skanowanie zakresu przy użyciu daty, aby pobrać wszystkie wiersze dla daty.Następnie filtruje ten zestaw przy użyciu wartości z tablicy. Jeśli jednak podam listę identyfikatorów jako listę liczb, optymalizator użyje indeksu w porządku:

select v.id from v_a v
where v.id in (123, 234, 345, 456, 567, 678, 789)
and   v.hist_date = input_date
and   v.status_new = 'CLOSED';

Problem również nie istnieje, gdy idzie się bezpośrednio przeciwko TBL_A (i mam obejście, które to robi, ale nie jest idealne.) Czy istnieje sposób, aby uzyskać optymalizator, aby najpierw pobrać wartości tablicy i użyć ich jako predykatów podczas uzyskiwania dostępu stół? Lub dobry sposób na restrukturyzację widoku, aby to osiągnąć?

questionAnswers(1)

yourAnswerToTheQuestion