Oracle bruger ikke indekset, fordi det antager select column_value from table(x)
returnerer 8168 rækker.
Indekser er hurtigere til at hente små mængder data. På et tidspunkt er det hurtigere at scanne hele bordet end gentagne gange at gå i indekstræet.
Det er svært nok at estimere kardinaliteten af en almindelig SQL-sætning. Det er næsten umuligt at skabe et nøjagtigt estimat for procedurekoden. Men jeg ved ikke, hvor de fandt på 8168. Tabelfunktioner bruges normalt med pipelinede funktioner i datavarehuse, et stort antal giver mening.
Dynamisk sampling kan generere et mere nøjagtigt estimat og sandsynligvis generere en plan, der vil bruge indekset.
Her er et eksempel på et dårligt kardinalitetsestimat:
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 |
-------------------------------------------------------------------------
Sådan løser du det:
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)