bc52f7a2

Изменения


Если подключиться к схеме 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)


Содержание раздела