Изменения
Если подключиться к схеме outln (которая по умолчанию в Oracle 9 заблокирована) и посмотреть список имеющихся таблиц, окажется, что в Oracle 9 добавлена одна таблица. В схему входят следующие таблицы:
ol$ - SQL-операторы ol$hints - подсказки ol$nodes - блоки запроса
Третья таблица - новая; она используется для привязки списка подсказок к различным блокам во (внутренне переписанной) версии SQL-запроса. Также можно обнаружить, что список подсказок (ol$hints) дополнен подпробностями о длине и смещении фрагментов текста.
Столбцы всех трех таблиц представлены на рис. 2, причем, новые столбцы, появившиеся в версии Oracle 9, помечены звездочками.
ol$
OL_NAME VARCHAR2(30) SQL_TEXT LONG TEXTLEN NUMBER SIGNATURE RAW(16) HASH_VALUE NUMBER HASH_VALUE2 NUMBER *** CATEGORY VARCHAR2(30) VERSION VARCHAR2(64) CREATOR VARCHAR2(30) TIMESTAMP DATE FLAGS NUMBER HINTCOUNT NUMBER SPARE1 NUMBER *** SPARE2 VARCHAR2(1000) ***
ol$hints
OL_NAME VARCHAR2(30) HINT# NUMBER CATEGORY VARCHAR2(30) HINT_TYPE NUMBER HINT_TEXT VARCHAR2(512) STAGE# NUMBER NODE# NUMBER TABLE_NAME VARCHAR2(30) TABLE_TIN NUMBER TABLE_POS NUMBER REF_ID NUMBER *** USER_TABLE_NAME VARCHAR2(64) *** COST FLOAT(126) *** CARDINALITY FLOAT(126) *** BYTES FLOAT(126) *** HINT_TEXTOFF NUMBER *** HINT_TEXTLEN NUMBER *** JOIN_PRED VARCHAR2(2000) *** SPARE1 NUMBER *** SPARE2 NUMBER ***
ol$nodes (новая таблица в версии 9)
OL_NAME VARCHAR2(30) CATEGORY VARCHAR2(30) NODE_ID NUMBER PARENT_ID NUMBER NODE_TYPE NUMBER NODE_TEXTLEN NUMBER NODE_TEXTOFF NUMBER
Рис. 2. Таблицы в схеме outln.
Пара нюансов бросается в глаза сразу -- представления, созданные на базе этих таблиц, не включают массу полезной информации. Хотя в таблице ol$hints и появилось 10 новых столбцов, определение представления user_outline_hints не изменилось. Фактически, это представление и в Oracle 8 было слишком урезанным, не включая, в частности, весьма информативный столбец hint#.
Обратите также внимание, что в Oracle 9 теперь есть два столбца hash_value. Если задать два одинаковых оператора на серверах Oracle 8 и Oracle 9, окажется, что значения в столбце hash_value для них совпадают, но вот добавленный в Oracle 9 столбец hash_value2, скорее всего, имеет совсем другое значение.
Также можно обнаружить, что сигнатура (значение столбца
signature) в Oracle 9 отличается от соответствующего значения в Oracle 8. Это связано с принципиальным стратегическим изменением в новой версии, направленным на повышение вероятности использования хранимых шаблонов. В Oracle 8 хранимый шаблон использовался только если SQL-оператор совпадал с оператором в шаблоне буквально, с точностью до пробела, регистра символов и перевода строки. В Oracle 9 правила совпадения ослаблены, так что тексты операторов сравниваются после удаления повторяющихся "пробельных символов" и приведения текста к одному регистру. Например, следующие два оператора будут использовать один и тот же шаблон.
select * from t1 where id = 5;
SELECT * FROM T1 WHERE ID = 5;
Это стратегическое изменение привело к изменению сигнатуры для SQL-оператора, для которого первоначально генерируется план. Поэтому при переводе базы данных с сервера Oracle 8 на Oracle 9 придется перегенерировать хранимые шаблоны, - иначе может оказаться, что они более не используются. (На самом деле, пакет
outln_pkg с псевдонимом
dbms_outln включает специальную процедуру
update_signatures
для решения этой проблемы).
Самое же существенное изменение в таблицах версии 9, однако, состоит в намного более детальном описании текста запроса и объектов, которые он затрагивает. Прежде чем читать дальше, выполните операторы в примере, представленном на рис. 3, и просмотрите содержимое таблицы
ol$hints.
drop table t1;
create table t1 nologging as select rownum id, rownum n1, object_name, rpad('x',500) padding from all_objects where rownum <= 100;
alter table t1 add constraint t1_pk primary key (id);
create index t1_i1 on t1(n1);
analyze table t1 compute statistics;
create or replace outline demo_1 on select * from t1 where id = 5 and n1 = 10;
Рис. 3. Код примера.
В примере используется небольшая, простая таблица с двумя идентичными столбцами, для одного из которых задано ограничение первичного ключа (и, соответственно, создан уникальный индекс), а по другому - создан обычный, не уникальный индекс. Мы генерируем хранимый шаблон для типичного запроса, а затем посмотрим, что с ним можно будет сделать.
Если выполнить запросы, представленные на рис. 1, к плану
demo_1, сгенерированному этим примером, можно обнаружить, что с ним связано шесть следующих подсказок:
STAGE NODE HINT 3 1 NO_EXPAND 3 1 ORDERED 3 1 NO_FACT(T1) 3 1 INDEX(T1 T1_PK) 2 1 NOREWRITE 1 1 NOREWRITE
Как и ожидалось, четвертая строка показывает, что для доступа к таблице используется индекс по первичному ключу (
T1_Pk). Но что нам делать с этим хранимым шаблоном, если на самом деле необходимо, чтобы сервер Oracle использовал не уникальный индекс
T1_I1? В идеале хотелось бы изменить этот хранимый шаблон так, чтобы строка:
3 1 INDEX(T1 T1_PK)
была заменена строкой:
3 1 INDEX(T1 T1_I1)
Содержание раздела