Ответ 1
Вы можете использовать подсказку для запроса против представления, чтобы заставить Oracle использовать индекс в базовой таблице. Но вам нужно знать псевдоним базовой таблицы (если таковой имеется) в базовом представлении. Общий синтаксис будет /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */
Пример
1) Создайте таблицу с 10 000 идентичными строками и создайте индекс в таблице. Индекс не будет избирательным, поэтому Oracle не захочет его использовать
SQL> ed
Wrote file afiedt.buf
1 create table foo
2 as
3 select 1 col1
4 from dual
5* connect by level <= 10000
SQL> /
Table created.
SQL> create index idx_foo on foo(col1);
Index created.
2) Убедитесь, что индекс не используется нормально, но что Oracle будет использовать его с подсказкой
SQL> set autotrace traceonly;
SQL> select * from foo where col1 = 1;
10000 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1245013993
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| FOO | 10000 | 126K| 7 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
713 consistent gets
5 physical reads
0 redo size
172444 bytes sent via SQL*Net to client
7849 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL> select /*+ index(foo idx_foo) */ *
2 from foo
3 where col1 = 1;
10000 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 15880034
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 25 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_FOO | 10000 | 126K| 25 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("COL1"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
715 consistent gets
15 physical reads
0 redo size
172444 bytes sent via SQL*Net to client
7849 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
3) Теперь создайте представление. Убедитесь, что обычные запросы к представлению не используют индекс, но заставляют индекс использоваться, указывая как псевдоним представления в запросе, так и псевдоним таблицы из определения представления
SQL> create view vw_foo
2 as
3 select col1
4 from foo f;
View created.
SQL> select col1
2 from vw_foo
3 where col1 = 1;
10000 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1245013993
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| FOO | 10000 | 126K| 7 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
16 recursive calls
0 db block gets
715 consistent gets
0 physical reads
0 redo size
172444 bytes sent via SQL*Net to client
7849 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL> select /*+ index(vf f idx_foo) */ col1
2 from vw_foo vf
3 where col1 = 1;
10000 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 15880034
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 25 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_FOO | 10000 | 126K| 25 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("COL1"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
14 recursive calls
0 db block gets
717 consistent gets
0 physical reads
0 redo size
172444 bytes sent via SQL*Net to client
7849 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
Тем не менее, все сказанное, однако, подсказки в целом являются последним средством при попытке настроить запрос - в общем случае предпочтительнее выяснить, какая информация отсутствует у оптимизатора, и предоставить соответствующую статистику, чтобы он мог сделать правильный выбор на свой. Это гораздо более стабильное решение в будущем. Вдруг так, когда вы сводились к указанию намеков, которые связаны с несколькими слоями псевдонимов - слишком легко для кого-то, касающегося определения представления, чтобы разбить ваш запрос, изменив псевдоним имени таблицы, например.