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

1 ... 241 242 243 [ 244 ] 245 246 247 ... 469


1142

Глава 14

tkyte@TKYTE816> create index local nonprefixed on partitioned table (b)

local;

Index created.

Теперь вставим данные в один фрагмент и пометим фрагменты индексов как не используемые (UNUSABLE):

tkyte@TKYTE816> insert into partitioned table values (1, 1) ;

1 row created.

tky1e@TKIE816> alter index local prefixed modify partition part2 unusable; Index altered.

tkyte@TKni816> alter index localnonprefixed modify partition part2 unusable;

Index altered.

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

tkyte@TKYTE816> set autotrace on explain

tkyte@TKYTE816> select * from partitioned table where a = 1 and b = 1;

Execution Plan

0 SELECT STATEMENT Qptimizer=CHOOSE (Cost=l Card=l Bytes=2 6)

1 0 INDEX (RANGE SCAN) OF LOCAL PREFIXED (NON-UNIQUE) (Cost=l

Итак, запрос, использующий индекс LOCAL PREFIX, успешно выполнен. Оптимизатор смог исключить фрагмент PART 2 индекса LOCAL PREFIX из рассмотрения, поскольку в запросе задано условие А=1. Нам помогло игнорирование фрагмента. Для второго запроса:

tkyte@TKYTE816> select * from partitioned table where b = 1;

ERROR:

ORA-01502: index TKYTE.LOCAL NONPREFIXED or partition of such index is in unusable state no rows selected Execution Plan

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=l Card=2 Bytes=52)

1 0 PARTITION RANGE (ALL)

2 1 TABLE ACCESS (BY LOCAL INDEX ROWID) OF PARTITIONED TABLE

3 2 INDEX (RANGE SCAN) OF LOCAL NONPREFIXED (NON-UNIQUE)

Оптимизатор не смог исключить из рассмотрения фрагмент PART 2 индекса LOCAL NONPREFIXED. С этим и связана проблема производительности при исполь-



Фрагментация 1143

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

Если удалить индекс LOCAL PREFIXED и еще раз выполнить исходный, успешно выполненный запрос:

tkyte@TK:E816> select * from partitionedtable where a = 1 and b = 1;

Execution Plan

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=l Card=l Bytes=26)

1 0 TABLE ACCESS (BY LOCAL INDEX ROWID) OF PARTITIONED TABLE

2 1 INDEX (RANGE SCAN) OF LOCAL NONPREFIXED (NON-UNIQUE) (Cost=l

Этот результат может показаться удивительным. Почти такой же план выполнения, как и в случае неудавшегося запроса, но на этот раз все работает. Причина в том, что оптимизатор может пропускать фрагменты даже для локально фрагментированных индексов без префикса (в этом плане нет шага PARTITION RANGE(ALL)).

Если к представленной выше таблице часто выполняются запросы вида:

select ... from partitioned table where a = :a and b = :b; select ... from partitioned table where b = :b;

имеет смысл создать локально фрагментированный индекс без префикса по столбцам (Ь,а); он пригодится для обоих представленных выше запросов. Локально фрагментиро-ванн1й индекс с префиксом по столбцам (а,Ь) пригодится только для первого запроса.

Однако при использовании фрагментированных индексов в соединениях результаты могут быть другими. В представленных выше примерах сервер Oracle по условию запроса мог во время оптимизации определить, можно или нельзя пропустить фрагменты. Это б1ло понятно по условию в конструкции WHERE (даже если в нем использовались связываемые переменные). Когда доступ по индексу используется в качестве начального, основного метода доступа, особой разницы между локально фрагментирован-ными индексами с префиксом и без префикса нет. При соединении с локально фрагментированным индексом, однако, все меняется. Рассмотрим следующую таблицу, фрагментированную по диапазону:

tkyte@TKYTE816> CREATE TABLE range example

2 (range key column date,

3 x int,

4 data varchar2(20)

6 PARTITION BY RANGE (range key column)

7 (PARTITION part l VALUES LESS THAN

8 (to date(01-]an-1995, dd-mon-yyyy)),

9 PARTITION part 2 VALUES LESS THAN

10 (to date(01-jan-1996,dd-mon-yyyy))

11 )



1144

Глава 14

12 /

Table created.

tkyte@TKYTE816> alter table range example

2 add constraint range example pk

3 primary key (range key column,x)

4 using index local

Table altered.

tkyte@TKYTE816> insert into range example values (to date(01-jan-1994), 1,

xxx);

1 row created.

tkyte@KYTE816> insert into rangeexample values (to date(01-jan-1995), 2, xxx);

1 row created.

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

tkyte@TKYTE816> create table test (pk, range key column, x,

2 constraint test pk primary key(pk))

3 as

4 select rownum, range key column, x from range example

Table created.

tkyte@TKYTE816> set autotrace on explain

tkyte@TKYTE816> select * from test, range example

2 where test.pk - 1

3 and test.range key column = range example.range key column

4 and test.x = range example.x

PK RANGE KEY X RANGE KEY X DATA

1 01-JAN-94 1 01-JAN-94 1 xxx

Execution Plan

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=l Bytes=69)

1 0 NESTED LOOPS (Cost=2 Card=l Bytes=69)

2 1 TABLE ACCESS (BY INDEX ROWID) OF TEST (Cost=l Card=l

3 2 INDEX (RANGE SCAN) OF TEST PK (UNIQUE) (Cost=l Card=l)

4 1 PARTITION RANGE (ITERATOR)

5 4 TABLE ACCESS (BY LOCAL INDEX ROWID) OF RANGE EXAMPLE

6 5 INDEX (UNIQUE SCAN) OF RANGE EXAMPLE PK (UNIQUE)



1 ... 241 242 243 [ 244 ] 245 246 247 ... 469

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