Базы данных Oracle - статьи

         

У вас реляционная база данных?


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

create table child ( id_p number(12,6), seq_c number(10), v1 varchar2(10), padding varchar2(100), constraint c_fk_p foreign key (id_p) references parent, constraint c_pk primary key (id_p, seq_c) using index local ) partition by range(id_p) ( partition p1000 values less than (1000), partition p3000 values less than (3000), partition p5000 values less than (5000) );

Обратите внимание, кстати, как эта подчиненная таблица (с ограничением внешнего ключа) создана в соответствии с границами секций главной таблицы - эта архитектура помогает добиться специальной оптимизации соединения на уровне секций.

Когда вы начнете экспериментировать со связями главная-подчиненная, то обнаружите, что обмен секций жестко ограничен, если только не начать повсеместно переводить ограничения в состояние novalidate.

А потом все становится ещё хуже! Если вы когда-то решите удалить старые секции, это можно сделать простым оператором:

alter table child drop partition p1000; alter table parent drop partition p1000;

Если вы попытаетесь выполнить эти операторы на тестовом примере, который мы ранее использовали, то обнаружите, что они работают быстро и эффективно. К сожалению, наш тестовый пример весьма специфичен: удаляемые секции никогда не содержали никаких данных. Фактически же, при удалении пар секций в главной и подчиненной таблицах возникает три проблемы.

Первая проблема - если вы попытаетесь удалить пару секций главной/подчиненной таблицы, и в секции главной таблицы когда-либо были какие-то данные, то попытка удалить (или очистить, truncate) секцию главной таблицы приведет к выдаче сообщения об ошибке:

ORA-02266: unique/primary keys in table referenced by enabled foreign keys

Чтобы удалить секцию в главной таблице, придется отключить ограничение внешнего ключа - даже когда вы удаляете "очевидно" соответствующую секцию подчиненной таблицы. Это, конечно, вполне обоснованно, но интуитивно кажется "нечестным".

Вторая проблема - когда вы удаляете секцию, каждую секуию после нее надо перенумеровать (внутренне) в словаре данных. Представьте себе секционированную таблицу с 3000 секций и двумя локально секционированными индексами. При удалении первой секции сервер Oracle перенумеровывает 9000 строк в словаре данных - и делает это построчно. Один оператор drop

приводит к выполнению 9000 отдельных изменений. Это небыстро.

Наконец, как только вы выполнили первый оператор drop

(предположительно, для подчиненной таблицы), таблицы перестают быть одинаково секционированными - все соответствующие SQL-курсоры делаются недействительными (такое происходит при любой операции сопровождения с секциями) и оптимизируются заново, и оптимизатор не будет использовать посекционные соединения (partition-wise joins), пока не будет удалена соответствующая секция. Надо хорошо подумать, выбирая время для удаления секций.



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