Программирование >>  Oracle 

1 ... 228 229 230 [ 231 ] 232 233 234 ... 469


1102 Глава 13

DISTINCT OWNER FROM MY ALL OBJECTS при наличии созданного в примере материализованного представления может быть переписан, поскольку столбец OWNER доступен. Запрос же SELECT DISTINCT OBJECT TYPE FROM

MY ALL OBJECTS по материализованному представлению выполнить нельзя, поскольку в нем недостаточно данных.

Совместимость по соединениям. Можно ли получить результат соединения, требуемого исходным запросом, из материализованного представления.

Совместимость по соединениям можно продемонстрировать с помощью таблицы MY ALL OBJECTS и следующих таблиц:

tkyte@TKYTE816> create table tl (oer varchar2(30) , flag chard)) ;

Table created.

tkyte@TKYTE816> create table t2 (object type varchar2(30), flag char(l));

Table created.

Следующий запрос совместим по соединению с материализованным представлением, поэтому он будет переписан так, чтобы обращаться к материализованному представлению:

tkyte@TKYTE816>selecta.owner, count(*) , b.owner

2 from my all objects a, tl b

3 where a.owner = b.owner

4 and b.flag is not null

5 group by a.owner, b.owner

Сервер может выяснить, что при использовании материализованного представления вместо исходной таблицы будет получен тот же ответ. Следующий запрос, однако, хотя и похож, но не совместим по соединению:

tkyte@TKYTE816> select a.owner, count(*) , b.object type

2 from my all objects a, t2 b

3 where a.object type = b.object type

4 and b.flag is not null

5 group by a.owner, b.object type

Столбец OBJECT TYPE в наше материализованное представление не входит, поэтому сервер Oracle не может переписать запрос так, чтобы он обращался к этому представлению.

Совместимость конструкций группировки

Она требуется, если и материализованное представление, и запрос содержат конструкцию GROUP BY. Если материализованное представление сгруппировано на необходимом или более высоком уровне детализации, запрос будет переписан с использованием материализованного представления. Запрос SELECT COUNT(*) FROM MY ALL OBJECTS GROUP BY 1, если выполнять его после представленного выше примера, представляет тот самый случай, когда материализованное представление сгруп-



Материализованные представления 1103

пировано на более высоком уровне детализации, чем необходимо. Сервер может переписать этот запрос с использованием материализованного представления, хотя критерии группировки в запросе и материализованном представлении не совпадают.

Совместимость конструкций агрегирования

Такая совместимость требуется, если и запрос, и материализованное представление содержат функции агрегирования. Она гарантирует, что материализованное представление обеспечит данные для необходимых агрегатов. В некоторых случаях возможны очень интересные варианты переписывания. Например, сервер распознает, что AVG(X) - то же самое, что и SUM(X)/COUNT(X), так что запрос, требующий выбора AVG(X), может быть выполнен по материализованному представлению, содержащему значения SUM и COUNT.

Во многих случаях простое применение описанных выше правил позволит серверу Oracle переписать запрос так, чтобы он обращался к материализованному представлению. В других случаях (как будет показано далее) серверу потребуется помощь администратора. Надо предоставить серверу дополнительную информацию, чтобы он смог использовать для ответа на запрос материализованное представление.

Как гарантировать использование представлений

В этом разделе мы научимся это делать - сначала с помощью требований, помогающих использовать переписывание запроса, а потом с помощью измерений (dimensions), являющихся средством описания сложных взаимосвязей - иерархий данных.

Требования целостности

Меня часто спрашивали: Почему надо использовать первичный ключ? Почему просто не создать уникальный индекс? . Можно, конечно, создать и просто индекс, но ведь факт использования первичного ключа говорит намного больше, чем просто создание уникального индекса. То же самое можно сказать об использовании внешних ключей, требований NOT NULL и других. Они не только защищают данные от нежелательных изменений, но и добавляют информацию о данных в словарь данных. На основе этой дополнительной информации сервер Oracle сможет чаще и в более сложных случаях переписывать запрос.

Рассмотрим следующий небольшой пример. Скопируем таблицы ЕМР и DEPT из схемы пользователя SCOTT и создадим материализованное представление, соединяющее эти две таблицы. Это материализованное представление отличается от использованного в первом примере тем, что для него задана конструкция REFRESH ON DEMAND. Это означает, что для учета изменений в исходных данных это представление надо обновлять вручную:

tkyte@TKYTE816> create table emp as select * from scott.emp; Table created.

tkyte@TKYTE816> create table dept as select * from scott.dept;



1104 Глава 13

Table created.

tkyte@TKYTE816> alter session set query rewrite enabled=true; Session altered.

tkyte@TKYTE816> alter session set query rewrite integrity=enforced; Session altered.

tkyte@TKYTE816> create materialized view emp dept

2 build immediate

3 refresh on demand

4 enable query rewrite

5 as

6 select dept.deptno, dept.dname, count {*)

7 from emp, dept

8 where emp.deptno = dept.deptno

9 group by dept.deptno, dept.dname 10 /

Materialized view created.

tkyte@TKYTE816> alter session set optimizer goal=all rows; Session altered.

Поскольку базовые таблицы и полученное материализованное представление - очень небольшие, мы с помощью оператора ALTER SESSION принудительно потребуем использовать оптимизатор, основанный на стоимости, а не проанализируем таблицы, как обычно. Если сервер Oracle узнает , насколько малы эти таблицы, он не будет выполнять некоторые из желательных для нас оптимизаций. При использовании стандартной статистической информации, оптимизатор будет работать так, будто таблицы достаточно большие.

В данном случае мы предоставили серверу Oracle мало информации. Ему не известно, как соотносятся таблицы ЕМР и DEPT, какие столбцы являются первичными ключами и т.д. Теперь выполним запрос и посмотрим, что произойдет:

tkyte@TKYTE816> set autotrace on tkyte@TKYTE816> select count(*) from emp;

COUNT(*)

Execution Plan

0 SELECT STATEMENT Optimizer=ALL ROWS (Cost=l Card=l)

1 0 SORT (AGGREGATE)

2 1 TABLE ACCESS (FULL) OF EMP (Cost=l Card=82)

Запрос б]л выполнен к базовой таблице ЕМР. Теперь мы с вами знаем, что значение COUNT(*) намного эффективнее (особенно при большом количестве отделов и сотрудников в них) может быть получено из материализованного представления. В нем есть вся необходимая информация для подсчета количества сотрудников. Мы знаем об этом потому, что учитываем сведения о данных, неизвестные серверу Oracle:



1 ... 228 229 230 [ 231 ] 232 233 234 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика