"Предположим, у меня нет другого индекса, кроме
неявный для первичного ключа
(Emp_id). В этом случае будет выше
запрос перейти на этот неявный индекс? Как
произойдет расчет ROWID? "
Во-первых, «неявный индекс» является реальным индексом. Если мы создаем первичный или уникальный ключ для таблицы, и для столбца (ов) Oracle не существует индекса, мы создаем индекс с тем же именем, что и ограничение.
SQL> create table t72
2 ( emp_id number not null primary key
3 , name varchar2(10) not null
4 , age number(3,0) )
5 /
Table created.
SQL> select constraint_name from user_constraints
2 where table_name = 'T72'
3 and constraint_type='P'
4 /
CONSTRAINT_NAME
------------------------------
SYS_C001145039
1 row selected.
SQL> select index_type, uniqueness
2 from user_indexes
3 where index_name = 'SYS_C001145039'
4 /
INDEX_TYPE UNIQUENES
--------------------------- ---------
NORMAL UNIQUE
1 row selected.
SQL>
Во-вторых, фильтры запросов к столбцу AGE. Таким образом, оптимизатор будет игнорировать любой индекс EMP_ID. В этом случае база данных выполнит полное сканирование таблицы EMP, оценивая значение каждого извлекаемого столбца AGE. Для каждой записи, где AGE < 30
, она объединит номер объекта таблицы, номер блока, номер слота и номер файла в ROWID.
Если вы хотите больше узнать о ROWID, поиграйте с пакетом DBMS_ROWID. У Рене Найффенегера есть полезное руководство на его веб-сайте. Узнайте больше.
"Предположим, это был SELECT ROWID, имя
от emp, где emp_id> 100 ;. Было бы
запрос получить ROWID из
индекс emp_id? «
Есть один простой способ сказать: эксперименты. Сначала мы создаем индекс для таблицы с большим количеством записей и обновляем статистику:
SQL> create unique index big_i on big_emp (empno)
2 /
Index created.
SQL> exec dbms_stats.gather_table_stats(user, 'BIG_EMP', cascade=>true)
PL/SQL procedure successfully completed.
SQL>
Затем мы увидим, как Oracle справляется с запросом:
SQL> explain plan for
2 select empno, rowid from big_emp
3 where empno > 10000;
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------
Plan hash value: 3238483832
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 24319 | 403K| 16 (0)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| BIG_I | 24319 | 403K| 16 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("EMPNO">10000)
13 rows selected.
SQL>
Если Oracle может удовлетворить запрос только с помощью индексированных столбцов, он не касается таблицы. Очевидно, что здесь извлекается ROWID из индекса.