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



              

Как ускорить работу?


Вынесенный в название раздела вопрос мне задают постоянно. Все ищут, где бы сделать установку fast = true, предполагая, что настройка производительности базы данных выполняется на уровне СУБД. Мой опыт показывает, что более 80 процентов (часто — намного больше, до 100 процентов) всего повышения производительности достигается на уровне приложения, а не базы данных. Нельзя заниматься настройкой СУБД, пока не настроено приложение, использующее данные.

Со временем появился ряд установок, включая которые на уровне СУБД, можно снизить влияние грубых ошибок программирования. Например, в Oracle 8.1.6 добавлен новый параметр — CURSOR_SHARING=FORCE. Он позволяет включить автоматическое использование связываемых переменных. В результате запрос SELECT * FROM EMP WHERE EMPNO = 1234 автоматически переписывается в виде SELECT * FROM EMP WHERE EMPNO = :x. Это может существенно сократить количество полных разборов и уменьшить ожидание защелок в библиотечном кеше, которые описаны в главе об архитектуре, но (всегда есть но) может также иметь ряд побочных эффектов. Можно нарваться на проблему (или ошибку) при использовании этой возможности, как, например, в первоначальной версии:

ops$tkyte@ORA8I.WORLD> alter session set cursor_sharing=force; Session altered.

ops$tkyte@ORA8I.WORLD> select * from dual where dummy='X'and 1=0; select * from dual where dummy='X'and 1=0 * ERROR at line 1: ORA-00933: SQL command not properly ended

ops$tkyte@ORA8I.WORLD> alter session set cursor_sharing=exact; Session altered.

ops$tkyte@ORA8I.WORLD> select * from dual where dummy='X'and 1=0; no rows selected

Принятый способ переписывания запроса дает некорректный результат в версии 8.1.6 (из-за отсутствия пробела между 'X' и ключевым словом AND). В итоге запрос приобретает вид:

select * from dual where dummy=:SYS_B_0and :SYS_B_1=:SYS_B_2;

Ключевое слово AND стало частью имени связываемой переменной :SYS_B_0. В версии 8.1.7, однако, этот запрос переписывается так:

select * from dual where dummy=:"SYS_B_0"and :"SYS_B_1"=:"SYS_B_2";




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