Oracle не използва индекса, защото предполага select column_value from table(x)
връща 8168 реда.
Индексите са по-бързи за извличане на малки количества данни. В даден момент е по-бързо да сканирате цялата таблица, отколкото многократно да обхождате дървото на индекса.
Оценяването на кардиналността на обикновен SQL оператор е достатъчно трудно. Създаването на точна оценка за процедурния код е почти невъзможно. Но не знам откъде са измислили 8168. Функциите за таблици обикновено се използват с конвейерни функции в хранилища за данни, доста голямо число има смисъл.
Динамично вземане на проби може да генерира по-точна оценка и вероятно да генерира план, който ще използва индекса.
Ето пример за лоша оценка на кардиналността:
create or replace type type_table_of_number as table of number;
explain plan for
select * from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));
Plan hash value: 1748000095
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8168 | 00:00:01 |
| 1 | COLLECTION ITERATOR CONSTRUCTOR FETCH| | 8168 | 00:00:01 |
-------------------------------------------------------------------------
Ето как да го поправите:
explain plan for select /*+ dynamic_sampling(2) */ *
from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));
Plan hash value: 1748000095
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Time |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 7 | 00:00:01 |
| 1 | COLLECTION ITERATOR CONSTRUCTOR FETCH| | 7 | 00:00:01 |
-------------------------------------------------------------------------
Note
-----
- dynamic statistics used: dynamic sampling (level=2)