В режиме по умолчанию (интерпретация) код частично компилируется, а частично интерпретируется во время выполнения. PL/SQL
выполняется в виртуальной машине; сначала код транслируется в виртуальный машинный код, иногда называемый байткодом или m-кодом. По сути происходит то же самое, что и при выполнении программ Java
. Когда приходит время выполнять код, байт-код транслируется (интерпретируется) в вызовы системных функций.
Но когда код начнет нормально работать, для повышения эффективности программ PL/SQL
можно приказать базе данных преобразовать байт-код в машинный код на более ранней стадии, во время компиляции (так называемый низкоуровневый режим). В результате база данных будет динамически загружать откомпилированный машинный код во время выполнения.
Когда используется режим интерпретации
Итак, если низкоуровневый режим работает быстрее, зачем выполнять программы в режиме интерпретации? Попробуем взглянуть на этот вопрос под другим углом. Целью низкоуровневого режима является высокая скорость выполнения. Таким образом, чтобы добиться максимальной скорости, вы поднимаете уровень оптимизации и пытаетесь выполнить как можно большую часть работы (включая раннее преобразование в машинный код) до стадии выполнения. В ходе разработки и модульного тестирования кода средства отладки важнее высокой скорости выполнения. Если вам понадобится выполнить исходный код в пошаговом режиме с заходом в подпрограммы, вас наверняка не устроит перестановка исходного кода оптимизирующим компилятором (уровень оптимизации 2) или подстановка подпрограмм (уровень оптимизации 3). Итак, во время отладки следует использовать уровень оптимизации 0 или 1; на этой стадии полезность низкоуровневого режима уже не так очевидна. Я рекомендую применять выполнение в режиме интерпретации в среде разработки.
Когда используется низкоуровневый режим
Низкоуровневый режим ориентирован на скорость. Программа запускается в низкоуровневом режиме, когда она уже отлажена и должна работать с максимальной скоростью. Компиляция в низкоуровневый код идет рука об руку с более высокими уровнями оптимизации. Обычно эта конфигурация применяется для окончательных версий программ, а также в некоторых тестовых средах. В низкоуровневом режиме время компиляции слегка увеличивается, потому что компилятору приходится выполнять больше работы, но программа и выполняется быстрее, чем в режиме интерпретации (по крайней мере не медленнее). Обратите внимание: компиляция PL/SQL
предоставляет наименьший выигрыш в производительности подпрограмм, основное время которых тратится на выполнение SQL
. Кроме того, при одновременном выполнении многих подпрограмм, откомпилированных в низкоуровневом режиме, потребуется выделить большой объем общей памяти, что может повлиять на производительность системы. По рекомендациям Oracle
, этот эффект начинает проявляться примерно от 15 000 одновременно откомпилированных программ.
низкоуровневая компиляция и версии Oracle
Способ настройки низкоуровневой компиляции и выполнения зависит от версии базы данных. Подробности приведены в главе 20, а ниже приведена краткая сводка возможностей компиляции в разных версиях.
Oracle9i Database. Возможность низкоуровневой компиляции программ появилась в Oracle9i
. В этой версии компиляция работала неплохо... если вы не использовали технологию RAC
(Real Application Clusters
) и не возражали против сложной процедуры резервного копирования. Базы данных RAC
создавали проблемы (они не поддерживались), а резервная копия базы данных должна была включать общие библиотеки, которые не сохранялись программой Oracle Recovery Manager
(RMAN
).
Oracle Database 10g. В Oracle Database 10g
низкоуровневая компиляция была усовершенствована. Базы данных RAC
и общие серверы поддерживались, но администратору был необходим компилятор C и копии общих библиотек на каждом узле RAC
. Проблемы с резервным копированием оставались — по-прежнему в него необходимо было включать общие библиотеки, но программа RMAN
эти библиотеки не сохраняла.
Oracle Database 11g. В Oracle Database 11g низкоуровневая компиляция была снова усовершенствована. Теперь компилятор C перестал быть необходимым, а общие библиотеки хранятся в словаре данных, что позволяет любой программе резервного копирования (по крайней мере, работающей с базами данных Oracle
) легко их найти и скопировать. Итак, с исчезновением проблем с резервным копированием и управлением общими библиотечными файлами ничто не мешает вам применять низкоуровневую компиляцию в рабочих и тестовых базах данных. Попробуйте — вам понравится.
Что необходимо знать
Так ли необходимо знать все, о чем рассказано в этой серии статей (начало здесь)? Конечно, нет. С другой стороны, ваш администратор базы данных, вероятно, должен знать большую часть этого материала.
Помимо удовлетворения здорового любопытства, этот материал должен был рассеять некоторые распространенные заблуждения по поводу архитектуры PL/SQL
. Как бы то ни было, вы должны помнить некоторые важные обстоятельства, относящиеся к внутренним механизмам PL/SQL
.
- Чтобы избежать лишних затрат при компиляции, часто вызываемый код следует оформить в виде хранимых программ (вместо анонимных блоков).
- Кроме своей уникальной возможности сохранения состояния во время сеанса, пакеты
PL/SQL
обладают преимуществами из области производительности. Большая часть логики приложения должна размещаться в телах пакетов. - При обновлении
Oracle
новые возможности компилятораPL/SQL
необходимо тщательно протестировать. В некоторых (достаточно редких) случаях переход наOraclellg
сопровождается небольшими изменениями в порядке выполнения (в соответствии с решениями, принимаемыми оптимизирующим компилятором), которые могут повлиять на результаты приложения. - Хотя автоматическое управление зависимостями
Oracle
избавляет разработчика от многих хлопот, к обновлению приложений на реально используемой базе данных следует относиться в высшей степени осторожно из-за необходимости блокировки объектов и сброса состояния пакетов. - Если вы используете удаленную проверку зависимостей на базе сигнатур при удаленных вызовах процедур, создайте процедуры для устранения возможности ложноотрицательных срабатываний (приводящих к ошибке времени выполнения).
- Используйте модель разрешений создателя для достижения максимальной производительности, а также упрощения управления и контроля за привилегиями доступа к таблицам баз данных. Модель разрешений вызывающего применяется только для решения конкретных проблем (например, программ, использующих динамический
SQL
с созданием или уничтожением объектов баз данных). - Технологические решения
Oracle
по минимизации машинных ресурсов, необходимых для выполненияPL/SQL
, иногда нуждаются в небольшом содействии со стороны разработчиков и администраторов — например, явном освобождении неиспользуемой памяти. - Там, где это оправдано логикой приложения, используйте идиому курсорных циклов
FOR
вместо открытия/цикла выборки/закрытия, чтобы пользоваться преимуществами автоматической массовой привязки вOracle10g
и последующих версиях. - Если ваша программа открывает явный курсор в программе
PL/SQL
, не забудьте закрыть курсор после завершения выборки данных. - Низкоуровневая компиляция
PL/SQL
может не обеспечивать значительного выигрыша в быстродействии приложений, интенсивно использующихSQL
, но в программах с большим объемом вычислений выигрыш может быть значительным. - Используйте программные переменные во встроенных статических командах
SQL
вPL/SQL
и переменные привязки в динамических командахSQL
, чтобы не препятствовать совместному использованию курсоров.