Развертывание огромного пакета PLSQL через JDBC невероятно медленно - PullRequest
2 голосов
/ 24 февраля 2011

Мне нужно развернуть очень большие пакеты PLSQL через JDBC, и у меня очень большая продолжительность развертывания.Я знаю, что не стоит использовать пакеты, содержащие до 25 000 строк кода, но сейчас у меня нет выбора.Развертывание такого пакета занимает около 2,5 часов через JDBC.

Я читаю пакет из файловой системы с упаковкой FileReader в BufferedReader.Я анализирую его построчно, проверяю разделитель и добавляю каждую строку в StringBuilder до тех пор, пока инструкция не будет завершена.Затем я использую StringBuilders toString () и передаю полученную строку в мои операторы execute ().

Спасибо за совет!

Ответы [ 2 ]

1 голос
/ 27 ноября 2011

Пакеты Oracle PL / SQL состоят из:

  • заголовок пакета - спецификация, аналогичная файлам C .h
  • тело пакета - эквивалент файла .c

Загрузка заголовка пакета сделает недействительными все пакеты PL / SQL, которые используют функции / процедуры / записи / константы / объекты / типы из этого пакета - обычно все, что ссылается или использует что-то из пакета.

Укажите PACKAGE, чтобы перекомпилировать как спецификацию пакета, так и тело пакета, если оно существует, независимо от того, являются ли они недействительными. Это по умолчанию. Перекомпиляция спецификации пакета и тела приводит к аннулированию и перекомпиляции зависимых объектов, как описано для SPECIFICATION и BODY.

База данных также делает недействительными все объекты, которые зависят от emp_mgmt. Если впоследствии вы ссылаетесь на один из этих объектов, не перекомпилировав его в явном виде, то база данных неявно перекомпилирует его во время выполнения.

источник: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/alter_package.htm

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

Перекомпиляция тела пакета не делает недействительными объекты, которые зависят от спецификации пакета.

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

источник: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/alter_package.htm

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

  • @pkg_a.sql - зависимости недействительны и попытка перекомпиляции происходит
  • @pkg_b.sql - так же, как и выше
  • @pkg_c.sql - так же, как и выше

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

Этот сценарий можно значительно улучшить, разбив пакеты на .pks (содержит только заголовок) и .pkb (содержит только тело). Сначала загрузите файлы заголовков, а затем загрузите тела.

  • @pkg_a.pks - зависимости недействительны, но не перекомпилированы
  • @pkg_b.pks - так же, как и выше
  • @pkg_c.pks - так же, как и выше
  • @pkg_a.pkb - pkg_a успешно перекомпилирован, поскольку все заголовки обновлены
  • @pkg_b.pkb - так же, как и выше
  • @pkg_c.pkb - так же, как и выше

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

Разделение пакетов на файлы заголовка и тела также позволит вам избежать загрузки файлов заголовков, которые не изменились. Это довольно часто, так как большинство изменений вносятся в тело (реальный код) библиотеки. Пропуск ненужной загрузки заголовка пакета приведет к тому, что меньше пакетов будет признано недействительным, а значит - меньше работы для проверки всей базы данных.

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

0 голосов
/ 02 марта 2011

Я не думаю, что ваше длительное время развертывания пакетов связано с процессом загрузки Java, JDBC, а скорее с управлением пакетами баз данных Oracle.

Когда вы выполняете CREATE PACKAGE BODY FOO..., программное обеспечение СУБД сначала проверяет, чтобы убедиться, что никто из других пользователей в системе не использует пакет (через блокировки базы данных).Если это так, ваш процесс зависает до тех пор, пока все остальные пользователи не закончат использование пакета.Затем он фиксирует ваш пакет в базе данных.Один из способов проверить это - переименовать пакет (в исходном исходном файле) и попробовать загрузить его.Если это не займет 2,5 часа, это может быть фактором.

Другая вещь, которую RDMBS делает при запуске оператора, - это компилирование пакета, которое включает проверку всех ссылок в вашем коде (например, таблиц, представлений, других пакетов) и генерацию закодированной версии.Для большого пакета время компиляции может быть значительным.Способ проверить это - запустить оператор ALTER PACKAGE FOO COMPILE; и рассчитать время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...