Динамическое разбиение таблиц в Oracle

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

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


person Eduardo Z.    schedule 03.02.2010    source источник


Ответы (4)


В 11g мы можем определить разделы INTERVAL, и Oracle автоматически создаст новые разделы, когда получит новые записи, ключи которых не соответствуют ни одному из существующих диапазонов. Это очень классная функция. Подробнее.

Следует иметь в виду, что разбиение на разделы является платным дополнением к лицензии Enterprise Edition. Так что это не дешевое использование.

person APC    schedule 03.02.2010
comment
+1 Введение разбиения INTERVAL устраняет большую часть необходимости в собственных решениях для автоматического управления добавлением разделов. Единственное улучшение, которое я бы хотел, чтобы Oracle предоставил, — это какой-то способ определить маску формата для сгенерированных имен разделов — теперь они генерируются с общими именами, сгенерированными системой, и мне всегда приходится смотреть на столбец LONG HIGH_VALUE в x_tab_partitions для получения значимой информации. про интервал. - person dpbradley; 03.02.2010
comment
@dpbradley - мне не посчастливилось использовать Partitioning в 11g по-настоящему, но я вижу, что это будет довольно раздражать. - person APC; 03.02.2010
comment
Просто предупреждение: вы не можете смешивать ссылочное разбиение с интервальным разбиением. Мы решили использовать ссылочное секционирование, а затем вручную свернуть задание для создания ежемесячных секций с нашим предпочтительным соглашением об именах. - person PenFold; 03.02.2010
comment
@dpbradley, твоя ссылка не работает - person Nathan Feger; 27.01.2011
comment
Хотя интервальное разбиение — отличный шаг в правильном направлении, оно имеет некоторые серьезные недостатки в зависимости от того, что вы делаете. Основными из них для меня являются сложность удаления старых разделов и ограничение на количество потенциальных разделов, которые вы можете иметь. - person Burhan Ali; 08.09.2013
comment
@BurhanAli - и как эти ограничения проявляются в вашей ситуации? - person APC; 09.09.2013
comment
Наш продукт на работе содержит множество разделов скользящих исторических данных (5-минутные разделы на срок до года) с использованием ранжированного секционирования. Мы попробовали интервал, и его было легко добавить, но больно было отказаться от конца. Проблему с ограничением на количество разделов не могу кратко описать в комментарии. Я не говорю, что интервальное разбиение — это плохо; просто это не волшебная пуля для всех ситуаций. - person Burhan Ali; 09.09.2013

вы можете автоматизировать процесс создания или усечения разделов с помощью динамический SQL. Вы должны написать процедуры либо с EXECUTE IMMEDIATE или DBMS_SQL и вы бы запланировали их с помощью DBMS_JOB< /a> или DBMS_SCHEDULER (DBMS_SCHEDULER — это функция 10 г, и она более универсальна, чем DBMS_JOB).

Вы, вероятно, захотите сначала создать операторы разделов вручную, а затем автоматизировать процесс, когда будете уверены в DDL. Вы найдете весь синтаксис в документации для оператор ALTER TABLE.

person Vincent Malgrat    schedule 03.02.2010

Вот пример того, что я придумал для создания разделов с использованием SYSDATE и смещения. Мне пришлось создать параметры замены со строкой, объединенной с SYSDATE:

COLUMN temp_var new_value partition_name_01;
SELECT 'TABLE_NAME_' || TO_CHAR(SYSDATE - 3, 'YYYYMMDD') AS temp_var FROM dual;
COLUMN temp_var new_value partition_date_01;
SELECT TO_CHAR(SYSDATE - 3, 'SYYYY-MM-DD') || ' 00:00:00' AS temp_var FROM dual;
COLUMN temp_var new_value partition_name_02;
SELECT 'TABLE_NAME_' || TO_CHAR(SYSDATE - 2, 'YYYYMMDD') AS temp_var FROM dual;
COLUMN temp_var new_value partition_date_02;
SELECT TO_CHAR(SYSDATE - 2, 'SYYYY-MM-DD') || ' 00:00:00' AS temp_var FROM dual;
COLUMN temp_var new_value partition_name_03;
SELECT 'TABLE_NAME_' || TO_CHAR(SYSDATE - 1, 'YYYYMMDD') AS temp_var FROM dual;
COLUMN temp_var new_value partition_date_03;
SELECT TO_CHAR(SYSDATE - 1, 'SYYYY-MM-DD') || ' 00:00:00' AS temp_var FROM dual;
COLUMN temp_var new_value partition_name_04;
SELECT 'TABLE_NAME_' || TO_CHAR(SYSDATE, 'YYYYMMDD') AS temp_var FROM dual;
COLUMN temp_var new_value partition_date_04;
SELECT TO_CHAR(SYSDATE, 'SYYYY-MM-DD') || ' 00:00:00' AS temp_var FROM dual;
CREATE TABLE TABLE_NAME
(
   SEQ_NO                 NUMBER NOT NULL,
   INSERT_DATE            DATE NOT NULL,
   FIRST_NAME             VARCHAR2 (256 BYTE),
   LAST_NAME              VARCHAR2 (256 BYTE),
   ID_NUM                 NUMBER,
   ID_STATUS              NUMBER
)

PARTITION BY RANGE
   (INSERT_DATE)
   SUBPARTITION BY LIST
      (ID_STATUS)
      SUBPARTITION TEMPLATE (
         SUBPARTITION SP1 VALUES (0) TABLESPACE &tblspce,
         SUBPARTITION SP2 VALUES (1) TABLESPACE &tblspce,
         SUBPARTITION SP3 VALUES (2) TABLESPACE &tblspce)

   (
   PARTITION &partition_name_01
      VALUES LESS THAN
      (TO_DATE ('&partition_date_01',
                   'SYYYY-MM-DD HH24:MI:SS',
                   'NLS_CALENDAR=GREGORIAN')),

   PARTITION &partition_name_02
      VALUES LESS THAN
      (TO_DATE ('&partition_date_02',
                   'SYYYY-MM-DD HH24:MI:SS',
                   'NLS_CALENDAR=GREGORIAN')),

   PARTITION &partition_name_03
      VALUES LESS THAN
      (TO_DATE ('&partition_date_03',
                   'SYYYY-MM-DD HH24:MI:SS',
                   'NLS_CALENDAR=GREGORIAN')),
sysdate

   PARTITION &partition_name_04
      VALUES LESS THAN
      (TO_DATE ('&partition_date_04',
                   'SYYYY-MM-DD HH24:MI:SS',
                   'NLS_CALENDAR=GREGORIAN')))

ENABLE ROW MOVEMENT;
person John Fuller    schedule 05.01.2011

Есть продукт, который позаботится об этом автоматически. PartitionManager for Oracle обеспечивает автоматическое управление разделами на основе сохранения организации, включая очистку и архивирование старых данных, копирование статистики и т. д. Вы можете попробовать его на http://www.xyrosoft.com

person user2758538    schedule 08.09.2013
comment
В чем это преимущество по сравнению с тем, что уже предлагает Oracle? - person Burhan Ali; 08.09.2013