|
Программирование >> Oracle
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)
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |