Oracle no usa el índice porque asume select column_value from table(x)
devuelve 8168 filas.
Los índices son más rápidos para recuperar pequeñas cantidades de datos. En algún momento, es más rápido escanear toda la tabla que recorrer repetidamente el árbol de índice.
Estimar la cardinalidad de una instrucción SQL regular es bastante difícil. Crear una estimación precisa para el código de procedimiento es casi imposible. Pero no sé de dónde sacaron 8168. Las funciones de tabla normalmente se usan con funciones canalizadas en almacenes de datos, un número bastante grande tiene sentido.
Muestreo dinámico puede generar una estimación más precisa y probablemente generar un plan que utilizará el índice.
Este es un ejemplo de una mala estimación de cardinalidad:
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 |
-------------------------------------------------------------------------
He aquí cómo solucionarlo:
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)