DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Динамический SQL

В динамическом SQL (NDS - Native Dynamic SQL), как правило, тоже могут быть реализованы преимущества мягкого закрытия и повторного использования курсоров, но наилучшие результаты достигаются при использовании переменных связывания. Рассмотрим две процедуры, которые выполняют одинаковые действия, но в одной использованы переменные связывания, а в другой - конкатенация.


В списке открытых видим уже знакомый нам курсор:
Теперь трижды выполним версию с конкатенацией:
Сначала выполним трижды версию с переменными связывания:
Количество разборов и выполнений, как и ожидалось, равно 1 и 3:
Список открытых курсоров имеет такой вид в силу того, что сохраняется только самый последний из них - в надежде на повторное использование.

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


Динамический SQL - это мощный и удобный инструмент. При минимально продуманном использовании он позволяет получить все преимущества повторного использования курсоров, доступные в обычном PL/SQL.
Использование курсоров не только для запросов
Вместе с развитием СУБД Oracle развиваются и курсоры. Наряду с достижениями в повышении производительности, описанными в предыдущих разделах, расширилась и функциональность курсоров, которая больше не ограничивается выполнением запросов, - курсоры теперь интегрируются в приложения на уровне проектирования и компоновки. В этом разделе описаны не упоминавшиеся ранее дополнительные возможности работы с курсорами.
Массовая выборка, тип данных REF CURSOR, параметры курсора и курсорные выражения - все эти инструменты весьма полезны администратору базы данных, занимающемуся исследованием и улучшением производительности приложений. Особенно полезны рассматриваемые здесь средства в тех случаях, когда вы работаете с тяжело нагруженной базой данных и для вас очень важно свести к абсолютному минимуму количество затрагиваемых вами записей. Например, ссылочный тип REF CURSOR можно использовать для контроля доступа к данным из клиентского приложения, которое может даже не подозревать о способе структурирования таблиц. Параметры курсора позволяют расширить доступ к данным. (В главе 3 обсуждаются и другие способы достижения этой цели.) А курсорные выражения (вложенные курсоры) активно способствуют тому, чтобы выполнялись только те операции, которые действительно должны выполняться.
Массовая выборка
Если вы будете выбирать записи по одной в цикле PL/SQL, вы столкнетесь с повышенными накладными расходами на переключение контекста между SQL и PL/SQL для каждой записи. Это существенно увеличит общее время выполнения, особенно при большом числе записей. Уменьшить количество переключений контекста можно с помощью массовой выборки (BULK COLLECT INTO), запрашивающей записи порциями или все сразу.
Сначала рассмотрим пример выборки записей по одной:


Если таблица ORDERS содержит 100 записей, то будет выполнено 100 переключений контекста. Вот вариант этой программы с массовой выборкой.

Для больших наборов записей выигрыш в производительности может быть огромен, поэтому мы настоятельно рекомендуем вам при любой возможности использовать этот способ.
У массовой выборки есть и другое, менее очевидное преимущество: база данных не должна заботиться о согласованности данных по чтению на всем протяжении извлечения и обработки данных. Обратимся еще раз к предыдущему примеру. Если гипотетическая процедура DO_SOME- THING тратит пять секунд на обработку каждой из 100 записей, полученных из таблицы ORDERS, серверу Oracle придется более восьми минут поддерживать согласованную по чтению копию этих данных. Если таблица ORDERS участвует во множестве других операций DML, то сегмент отката базы данных должен будет заниматься поддержанием согласованного представления данных на всем протяжении этой длинной операции.
В данном случае есть одна потенциальная трудность, возникающая при переходе к массовой выборке: процедура DO_SOMETHING должна будет обрабатывать ситуации, когда записи, с которыми она собирается работать, уже не существуют, так как они были удалены за время, прошедшее с момента массовой выборки.

Альтернативный способ заключается в помещении всех полученных массовой выборкой записей в память и их последующей обработке. При таком подходе значительно уменьшаются шансы получить неприятную ошибку 0RA-01555 - Snapshot Too Old (сегмент отката слишком мал).
Так как массовая выборка помещает записи в память сеанса, следует учитывать ограничения на доступный сеансу объем памяти. Если для приложения критичны затраты памяти сеанса, то вы можете использовать предложение LIMIT для ограничения количества одновременно запрашиваемых записей. Например, так:

Я часто пользуюсь массовой выборкой при запросах к таблицам производительности Oracle (V$), так как меньше всего я хотел бы, чтобы БД занималась дополнительной работой только ради того, чтобы я мог посмотреть, например, сколько операций чтения и записи выполнил каждый из сеансов. Вот алгоритм, которого я придерживаюсь:

Рекомендую использовать эту возможность как можно чаще при запросах к сильно нагруженным представлениям производительности Oracle.
 









jAntivirus