2016-02-09 4 views
4

Периодически мне нужно отделить раздел от одной таблицы и прикрепить к другой таблице в другом табличном пространстве.Как избежать глобального индекса Oracle, восстановленного при перемещении раздела

Псевдо потока:

  • петли каждой таблицы и с истекшим сроком раздела:

    1.1 Создание нового целевого раздела в целевой таблице разделов

    1.2 Переместить целевое табличное пространство

    1.3 Обмен исходная перегородка в временную таблицу

    1.4 Обмен временной таблица с целевым разделом

    1,5 Капля источник раздел

  • Rebuild глобальных индексами в исходной таблице

  • Rebuild глобальных индексов в целевой таблице

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

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

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

Примечание:

  • Я мог бы использовать UPDATE GLOBAL пункт INDEXES в Partition Move и Partition биржи статей, но это дорого, и было бы называют несколько раз в цикле.
  • Я могу изменить глобальные индексы на локальные индексы, но это будет иметь большее влияние производительности на наше приложение. Кроме того, уникальный индекс не будет работать (ключ раздела не задействован).
+0

может изменить шаги, описанные Вы? Можно ли создать временную * копию * раздела? –

+0

Да, шаги могут быть изменены, основная цель - переместить раздел (данные, привязки, индекс) в другую таблицу в другом табличном пространстве. Я до сих пор не нашел эффективного способа копирования раздела. Все вышеперечисленные шаги в настоящее время выполняются за один сеанс с использованием PL/SQL. Все предложения приветствуются. – StevieL

+0

Боюсь, нет способа избежать этого. Кроме того, что новая функция 12c. Просто, когда вы используете глобальные индексы, вы теряете некоторые преимущества разделения. Кроме того, внутренний рекурсивный запрос, выполняемый разбиением на разделы, имеет в нем подсказку 'parallel (1)'. Таким образом, вы даже не можете сделать это быстрее. – ibre5041

ответ

0

Одним из возможных подходов будет копировать раздел перемещаться из ACT в таблице TMP (с использованием CTAS в необходимом табличном) и чем

  • Взамен таблицы TMP с разбиением Таблица HIST и
  • отбросьте раздел в таблице ACT.

Такой подход позволяет Асинхронный Global Maintenance Index, но как-то неделю точка в том, что этот шаг делается в два этапа, так что теоретически может быть запросы, которые видят оба раздела или нет раздела (в зависимости от й eorder из два шага).Если это проблема, необходимо принять дополнительную осторожность (например, заблокировать таблицу HIST).

Здесь приведен пример использования INTERVAL PARTITONING (установка таблицы ниже).

-- step 1 copy the partition to be moved from ACT table 
create table tmp as 
select * from t_act partition FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')); 

-- step 2 allocate partition in HIST table 
LOCK TABLE t_hist 
PARTITION FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) 
IN SHARE MODE; 


-- step 3 publish the copy in HIST table and DROP the ACT partition 
ALTER TABLE t_hist 
EXCHANGE PARTITION FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) 
WITH TABLE tmp 
INCLUDING INDEXES; 

alter table t_act drop partition FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) UPDATE INDEXES; 

Настройка Таблица

drop TABLE t_act; 
CREATE TABLE t_act 
(id number, 
transaction_date DATE not null, 
    vc_pad VARCHAR2(100) 
) 
PARTITION BY RANGE (transaction_date) 
INTERVAL (NUMTODSINTERVAL(1,'DAY')) 
    (
    PARTITION P_01 VALUES LESS THAN (TO_DATE('2016-02-22', 'YYYY-MM-DD')), 
    PARTITION P_02 VALUES LESS THAN (TO_DATE('2016-02-23', 'YYYY-MM-DD')) 
); 

ALTER TABLE t_act ADD CONSTRAINT t_act_pk PRIMARY KEY (id); 
create index t_act_ix1 on t_act(transaction_date); 

drop TABLE t_hist; 
CREATE TABLE t_hist 
(id number, 
transaction_date DATE not null, 
    vc_pad VARCHAR2(100) 
) 
PARTITION BY RANGE (transaction_date) 
INTERVAL (NUMTODSINTERVAL(1,'DAY')) 
    (
    PARTITION P_01 VALUES LESS THAN (TO_DATE('2016-02-20', 'YYYY-MM-DD')), 
    PARTITION P_02 VALUES LESS THAN (TO_DATE('2016-02-21', 'YYYY-MM-DD')) 
); 

insert into t_act 
select rownum, TO_DATE('2016-02-21', 'YYYY-MM-DD') ,'TEST' from dual connect by level <= 100000; 
commit; 
+0

Это хорошая альтернатива, но у меня есть проблема: поскольку я использую составной раздел (диапазон + хеш), у одного раздела диапазона все еще есть хеш-подразделы. поэтому я не могу использовать CTAS, который не создает разделы. Я могу создать временную таблицу заранее, но копирование данных с помощью INSERT..SELECT..FROM кажется мне медленным, так как это копия уровня записи. – StevieL

+0

@StevieL Вы можете ** создать секционированную таблицу с CTAS: 'create table tmp PARTITION BY HASH (id) PARTITIONS 4 как выбрать * из раздела t_act FOR (TO_DATE ('2016-02-21', 'YYYY- MM-DD ')) '. В качестве альтернативы вы можете использовать 'INSERT/* + APPEND * /', который будет иметь сопоставимую производительность с CTAS. –