Какво е виртуален индекс в Oracle?
- Виртуалният индекс е „фалшив“ индекс, чиято дефиниция съществува в речника на данните, но няма свързан сегмент на индекса.
- Много пъти съветникът за настройка на sql ви препоръчва да създадете нов индекс и искате да тествате новия индекс. В този случай може да отнеме доста време за добавяне на индекси към големи таблици и ще заеме голямо дисково пространство също ако таблицата е голяма. Също така допълнителните индекси са налични за използване от други сесии, което може да повлияе на производителността на други части на вашето приложение, което в момента не тествате. Това може да бъде особено проблематично, когато се опитвате да идентифицирате проблеми в производствена система. Виртуалните индекси решават този проблем
- Целта на виртуалните индекси е да симулират съществуването на индекс – без всъщност да се изгражда пълен индекс
- Това позволява на разработчиците да изпълняват план за обяснение, сякаш индексът присъства, без да чакат създаването на индекса да завърши и без да използват допълнително дисково пространство.
- Можем да анализираме виртуални индекси.
- Не можете да създадете отново виртуален индекс; хвърля ORA-8114:„Потребителят се опита да промени фалшив индекс“
- Можете да премахнете индекса просто като нормален индекс.
SQL> drop index <index_name>;
Важни точки, които трябва да запомните
(1) Трябва да зададем „_USE_NOSEGMENT_INDEXES“ на true на ниво сесия, за да използваме тази функция
(2) Виртуалните индекси се създават с добавяне на част без сегмент в края на скрипта за създаване на индекс
Пример за демонстриране на използването на виртуален индекс в Oracle
(1) Създайте примерна таблица, кажете virtual_test_t
SQL> create table virtual_test_t as select * from dba_objects where rownum < 100000;
(2) Изберете произволна стойност от таблицата
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
(3) Проверете плана Oracle Explain за заявката SELECT.
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
(4) Създайте виртуален индекс върху създадената таблица.
SQL> create index test_index_v on virtual_test_t(object_name) nosegment;
Не забравяйте, че за да създадете виртуален индекс, трябва да посочите клаузата NOSEGMENT в израза CREATE INDEX.
Отбележете също, като изпълните горния израз, сегмент на индекса не се създава.
(5) Можете да проверите същото със следното:
SQL> set autotrace off
SQL> select index_name from dba_indexes where table_name = 'VIRTUAL_TEST_T' and index_name = 'TEST_INDEX_V';
no rows selected
SQL> col OBJECT_NAME format a20;
SQL> select object_name, object_type from dba_objects where object_name = 'TEST_INDEX_V';
И така, обектът съществува в базата данни, но ние нямаме сегмент за същия.
(6) Сега стартирайте същото, за да проверите дали индексът се използва.
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
Можем ясно да забележим, че индексът не се използва.
(7) За да използваме създадения виртуален индекс, трябва да зададем параметъра _USE_NOSEGMENT_INDEXES на true.
SQL> alter session set "_USE_NOSEGMENT_INDEXES" = true;
Session altered.
(8) Сега изпълнете същия оператор SELECT.
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| VIRTUAL_TEST_T | 8 | 1416 | 5 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_INDEX_V | 216 | | 1 (0)| 00:00:01 |
След като зададете този скрит параметър, оптимизаторът на Oracle ще започне да използва виртуалния индекс, който сте създали в тази таблица.
Ако стартирате тази заявка от която и да е друга сесия, тя няма да използва този виртуален индекс (както сме използвали „alter сесия” изявление).