Oracle для профессионалов



              

Используйте связываемые переменные


Если бы мне пришлось писать книгу о том, как создавать немасштабируемые приложения Oracle, первая и единственная ее глава называлась бы "Не используйте связываемые переменные". Это — основная причина проблем, связанных с производительностью, и основная помеха масштабируемости. Особенности использования разделяемого пула Oracle (очень важной структуры данных разделяемой памяти) требуют от разработчиков использовать разделяемые переменные. Если надо замедлить работу приложения Oracle, вплоть до полного останова, — откажитесь от их использования.

Связываемая переменная — это подставляемый параметр запроса. Например, для получения записи доя сотрудника с номером 123, можно выполнить запрос:

select * from emp where empno = 123;

Но можно задать и другой запрос:

select * from emp where empno = :empno;

В обычной системе информацию о сотруднике с номером 123 могут запрашивать всего один раз. В дальнейшем будут запрашивать информацию о сотрудниках с номерами 456, 789 и т.д. При использовании в запросе литералов (констант) каждый запрос является для СУБД абсолютно новым, никогда ранее не выполнявшимся. Его надо разбирать, уточнять (определять объекты, соответствующие именам), проверять права доступа, оптимизировать и т.д. — короче, каждый выполняемый уникальный оператор придется компилировать при каждом выполнении.

Во втором запросе используется связываемая переменная, :empno, значение которой подставляется в запрос при выполнении. Этот запрос компилируется один раз, а затем план его выполнения запоминается в разделяемом пуле (в библиотечном кеше), из которого его можно выбрать для повторного выполнения. Различие между этими двумя вариантами в плане производительности и масштабируемости — огромное, даже принципиальное.

Из представленного выше описания вполне понятно, что разбор оператора с явными, жестко заданными константами (так называемый полный разбор) выполняется дольше и требует намного больше ресурсов, чем повторное использование уже сгенерированного плана запроса (его называют частичным разбором). Менее очевидным может оказаться, насколько постоянный полный разбор сокращает количество пользователей, поддерживаемых системой. Отчасти это связано с повышенным потреблением ресурсов, но в гораздо большей степени — с механизм защелок, используемых в библиотечном кеше. При полном разборе запроса СУБД будет дольше удерживать определенные низкоуровневые средства обеспечения последовательного доступа, которые называются защелками (подробнее о них см. в главе 3). Защелки защищают структуры данных в разделяемой памяти сервера Oracle от одновременного изменения двумя сеансами (иначе эти структуры данных Oracle в конечном итоге были бы повреждены) и от чтения этой структуры данных по ходу изменения другим сеансом. Чем чаще и на более продолжительное время на эти структуры данных устанавливаются защелки, тем длиннее становится очередь для установки этих защелок. Точно так же происходит при использовании длинных транзакций в среде MTS, — монополизируются критические ресурсы. Временами машина может казаться минимально загруженной, а СУБД работает очень медленно. Вполне вероятно, что один из сеансов удерживает защелку и формируется очередь в ожидании ее освобождения. В результате работа с максимальной скоростью невозможна. Достаточно одного неверно работающего приложения для существенного снижения производительности всех остальных приложений. Одно небольшое приложение, не использующее связываемые переменные, приводит со временем к удалению из разделяемого пула необходимых SQL-операторов других хорошо настроенных приложений. Достаточно ложки дегтя, чтобы испортить бочку меда.




Содержание  Назад  Вперед