СТАТЬЯ
20.12.01

Накопление, хранение и использование хронологических данных больших объемов в СУБД ORACLE

© Вл. Якушин
Статья была опубликована в журнале Oracle Magazine

В статье описывается загрузка из файлов типа dbf объемом 700 MB (> 3 млн. записей) в базу данных ORACLE объемом 4 GB (20 млн. записей). Проведение входного контроля и проверкой на уникальность при добавлении базу данных ORACLE. Программы загрузки и выгрузки разработаны с использованием OCI. Проверки и контроль организованы с использованием хранимых процедур, триггеров, промежуточных таблиц.

В статье сравнивается производительность при использовании различных вариантов загрузки и, кратко, дальнейшее использование накопленной информации при ее хранении в ORACLE.

Система реализована и эксплуатируется с 1.1.1998 года и до сих пор в Самарском Территориальном фонде обязательного медицинского страхования.

Цели построения системы

Требования к системе:

Концепция реализации системы

  1. Основная информация, хранимая и используемая в системе – это история изменений информации об объекте. Хранение и доступ организованы очень просто. Хранится несколько версий информации об одном объекте. Для каждой хранимой версии хранится период действия этой версии. На этапе загрузки информации обеспечивается контроль на возможность пересечения периодов действия для одного объекта, а также уникальность самого объекта по 8–12 ключам в любом периоде. Ссылочная целостность с другими таблицами выполняется тоже процедурно с учетом периодов действия записей обоих таблиц.
  2. Вся логическая обработка выполняется в СУБД ORACLE.
  3. Загрузка информации разбивается на несколько этапов.
  4. Нужно следить, чтобы исходная таблица была всегда в табличном пространстве в состоянии READ ONLY.
  5. Нужно следить, чтобы исходный и результирующий массив (таблица, файл) всегда находились на разных дисках. Кроме того, необходимо иметь еще отдельные диски для табличных пространств сегментов отката, индексов и временного табличного пространства TEMP.

Начальный входной контроль, выполняемый на уровне одной записи

Он может быть разбит на части, выполняться последовательно и параллельно и повторяться для исправленных записей.

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

Создается временная Load таблица для загрузки информации в виде, как она хранится в исходном файле.

Написана универсальная программа Загрузчик файлов формата DBF в СУБД ORACLE. Она распознает заголовок DBF файла, сравнивает его структуру с одноименной Load таблицей, и если необходимо добавляет в нее колонки или расширяет их. Скорость работы программа равна скорости работы SQL*Loader. Программа может работать в режиме клиент-сервер или локально на сервере в среде ОС Win95/NT, Linux, AIX.

Файл отсеянных записей имеет структуру исходного файла и дополнительные колонки:

В файл отсеянных записей попадают также записи с нарушением типа данных и соответствующей ошибкой ORACLE.

Проверка уникальности

Нужно оставить одну из нескольких записей об объекте с наиболее поздней датой ввода. Как оказалось на объемах 700 MB и порядка 3,5 млн. записей выявление неуникальных записей использовать поиск по индексу не эффективно, т.к. нужно произвести поиск 12 раз для каждой из 3,5 млн. записей. Для каждой из 12 проверок делается следующее (упрощенное описание):

Create table NO_UK_N1 tablespace …unrecoverable as
Select <поле1>, <поле2>, <поле3>, … <полеN>
From LOAD_TABLE
Where Deleted = 0
Group by <поле1>, <поле2>, <поле3>, … <полеN>
Having count (*) > 1

Выполнение этого запроса занимает порядка от 20 минут до 2 часов. При работе с индексами я несколько раз ждал дня 4 и снимал запрос. За три года многократных проб найдено правильное решение.

Затем для таблицы NO_UK_N1 создается уникальный индекс по всем колонкам и создается вторая таблица NO_UK_N1_1 c усеченными неуникальными записями:

Create table NO_UK_N1_1 tablespace …unrecoverable as
Select a.<поле1>, a.<поле2>, a.<поле3>, … a.<полеN>,
a.DATA, a.ROWID NROWID, 0 P, NULL RNROWID
From LOAD_TABLE a, NO_UK_N1 b
Where a.Deleted = 0
And a.<поле1> = b.<поле1> -- NOT NULL
And NVL(a.<поле2>, 0 ) = NVL(b.<поле2> ,0) -- NUMBER NULL
And NVL(a.<поле3>,‘*’) = NVL(b.<поле3> ,‘*’) --VARCHAR2 NULL

And a.<полеN>= b.<полеN> -- аналогично NULL для полей типа DATE

Затем для таблицы NO_UK_N1_1 создается не уникальный индекс по всем ключевым колонкам <поле1>, <поле2>, <поле3>, … <полеN>.

В PL/SQL блоке последовательно продвигаясь по таблице NO_UK_N1 и подчиненной таблице NO_UK_N1_1, отбирается наиболее поздняя запись по полю NO_UK_N1_1.DATA. При этом используется фраза ORDER BY DATA DESC. Первая выбранная по ключу таблицы NO_UK_N1 запись из NO_UK_N1_1 старшая. Эта запись остается. В ней можно изменить поле P. Для остальных можно записать поле RNROWID значением NROWID старшей записи. Эти записи отсеиваются. Для этих записей по значению NROWID в таблице LOAD_TABLE изменяется поле DELETED с 0 на номер обработки уникальности, т.е. в нашем случае на 1.

В результате этой обработки в таблице LOAD_TABLE появится часть записей со значением поля DELETED не равным 0. Это отсеянные записи по уникальности.

Выделение оставшихся записей

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

Для этого создается на другом диске табличное пространство в одном файле размером 650 МВ с возможностью авторасширения по 20 МВ. Создается таблица:

Create table UK_TABLE

PCTFREE 0 PCTUSED 99

INITIAL 648 MB NEXT 20 MB

tablespace TS_UK_TABLE unrecoverable
as
Select *
From LOAD_TABLE
Where Deleted = 0

Перегрузка информации

Производится перегрузка информации из таблицы LOAD_TABLE в таблицу, хранящую всю историю изменений информации об объекте. Это один из наиболее интенсивных и продолжительных этапов. Продолжительность выполнения на 64 разрядном сервере RISC IBM AIX составляет 80 – 110 часов.

Структура хранимой процедуры:

Необходимо обратно денормализовать информацию. И получить DBF файл.

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Обсудить на форуме Oracle
Отправить ссылку на страницу по e-mail


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован: 20.12.01