Почему Oracle SQL Optimizer игнорирует предикат индекса для этого представления?
Я пытаюсь оптимизировать набор хранимых процедур, которые идут против многих таблиц, включая это представление. Представление как таковое:
У нас есть TBL_A (id, hist_date, hist_type, other_columns) с двумя типами строк: исторический_тип 'O' против исторического_типа 'N'. Представление self присоединяет таблицу A к себе и транспонирует N строк против соответствующих O строк. Если для строки O не существует строки N, значения строки O повторяются. Вот так:
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 имеет уникальный индекс: (id, hist_date, hist_type). Он также имеет уникальный индекс: (hist_date, id, hist_type), и это первичный ключ.
Следующий запрос является предметом спора (в хранимой процедуре, где x объявлен как 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';
Этот запрос игнорирует индекс столбца id при обращении к TBL_A и вместо этого выполняет сканирование диапазона, используя дату, чтобы выбрать все строки для даты.затем это фильтры, которые устанавливают, используя значения из массива. Однако, если я просто приведу список идентификаторов в виде списка чисел, оптимизатор будет прекрасно использовать индекс:
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';
Эта проблема также не существует при прямом обращении к TBL_A (и у меня есть обходной путь, который делает это, но это не идеально.) Есть ли способ заставить оптимизатор сначала извлекать значения массива и использовать их в качестве предикатов при доступе Таблица? Или хороший способ реструктурировать взгляд для достижения этой цели?