16.06.2008, 12:12 | #1 |
Участник
|
Связываемые переменные при работе с Oracle
Недавно начал работать с Аксаптой, так что простите, если спрашиваю общеизвестные факты.
1) Правильно ли я понимаю, что Аксапта сама генерит запросы для Oracle. Причем делает это не используюя связываемые переменные. То есть вместо конструкции: select ... where a = :a and b = :b Все запросы на Oracle уходят с уже подставленными числами ? Насколько я понял, ситуация выглядит именно так и это приводит к тому, что Oracle приходится разбирать и строить планы выполнения для всех запросов. Другими словами, для каждого запроса Oracle приходится выполнять стадию parse, что приводит к долгим ожиданиям latch free. 2) Можно ли средствами Axapta повлиять на нее так, чтобы в ряде запросов она все-таки использовала связываемые переменные? 3) Кто-нибудь пробовал на рабочей базе Axapta включать опцию CURSOR_SHARING и к чему это приводило? Теоритические плюсы и минусы такого шага я понимаю - интересует именно специфика Аксапты. |
|
16.06.2008, 12:35 | #2 |
Участник
|
Ну, если я правильно понял, что связываемые переменные - это placeholders, то вообще-то везде должны по-умолчанию использоваться placeholders (начиная с версии 4.0)
А до этого для некоторых запросов (простых - без джоина таблиц определенных групп) тоже использовались placeholders. Можно явно указать системе, чтобы она использовала их в запросе. (для каждого запроса в отдельности) Но возможно с Ораклом что-то напортачили. |
|
16.06.2008, 20:59 | #3 |
Moderator
|
Цитата:
1. Из за того что Axapta везде использует case-insensitive сравнение, все индексы по строковым полям в Аксапте, при использовании Oracle, строятся как функциональные. То есть индекс строится не по полю custAccount, а по NLS_LOWER(Substr(custAccount,1,10)) (10 - длина поля) 2. При формировании запросов, литералы тоже заключаются в функцию NLS_LOWER. То есть - на сервер отправляется запрос вида select * from custTable where NLS_LOWER(Substr(custAccount,1,10)=NLS_LOWER(Substr('Рога и копыта'),1,10). Оптимизатору Оракла хватает ума сопоставить выражение в левой части равенства с выражением индекса 3. Если поставить CURSOR_SHARING=EXACT, Oracle транслирует полученный запрос в select * from custTable where NLS_LOWER(Substr(custAccount,:bind1,:bind2)=NLS_LOWER(Substr(:bind3,:bind4,:bind5), после чего подставляет конкретные значения bind-переменных. Нетрудно догадаться, что левая часть сравнения перестает сопоставляться с выражением индекса и индекс перестает использоваться для исполнения запроса. Это все было справедливо для Oracle 10g Release 1. Может в более поздних версиях это дело как-то изменили. Кстати - даже в отрыве от проблем с ораклом, я не вижу особого смысла в замене литералов на переменные запроса. На практике - узким местом в 95% случаев является не процессор, а жесткий диск. Использование переменных запроса слегка снижает нагрузку на процессор, но при этом значительно повышает вероятность генерации неправильного плана запроса. Кроме того - Аксапта не использует (ну хорошо - почти не использует ) хранимые процедуры, триггера, и вообще средства программирования сервера БД. Так что нагружать именно процессора сервера БД - там просто нечем. Так что, на мой взгляд, любые попытки массовой параметризации запросов приносят негативный результат именно в случае Аксапты. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
16.06.2008, 22:03 | #4 |
Модератор
|
Цитата:
Сообщение от fed
Кстати - даже в отрыве от проблем с ораклом, я не вижу особого смысла в замене литералов на переменные запроса. На практике - узким местом в 95% случаев является не процессор, а жесткий диск.
.. Так что, на мой взгляд, любые попытки массовой параметризации запросов приносят негативный результат именно в случае Аксапты. axbegin, почитайте, попробуйте покрутить настройки на AOS-е, связанные с литералами. Кстати, версию Вы не указали, а их немало
__________________
-ТСЯ или -ТЬСЯ ? |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
17.06.2008, 07:15 | #5 |
Moderator
|
Цитата:
А Кайт, кстати, не пишет о том, нафига нужна статистика и гистограмы, если все запросы жестко параметризованы ? |
|
17.06.2008, 10:01 | #6 |
Модератор
|
Цитата:
Цитата:
и ни разу не видел чтобы из за использования литералов перегружались процессора сервера БД
Пока что ни axbegin, ни я не говорили о ПЕРЕГРУЗКЕ сервера из-за того, что не используются связанные переменные. Речь шла об увеличении времени отклика Цитата:
А Кайт, кстати, не пишет о том, нафига нужна статистика и гистограмы, если все запросы жестко параметризованы ?
Мой посыл таков - идеальной настройки для всех случаев жизни нет. Но prepared execution по умолчанию (для основной массы OLTP-шных запросов) и осознанное использование forceliterals в коде x++ там, где это требуется - работает вполне прилично. По крайней мере, средняя температура по больнице (результаты любимого benchmark tool) это подтверждает
__________________
-ТСЯ или -ТЬСЯ ? |
|
17.06.2008, 10:20 | #7 |
Moderator
|
В общем - общий вывод простой. Универсального подхода не существует. Надо разбираться с каждым конкретным случаем. Использование литералов дает гарантированное увеличение нагрузки на процессора, использование переменных - увеличивает (но не гарантирует) шансы на генерацию некорректного плана запроса, что увеличиваетт нагрузку на жесткие диски и память. По моему убеждению, чаще всего на современных серверах, узким местом являются именно диски. Скажем - в 2003 году типичным сервером БД на внедрении Аксапты был двухпроцессорный Xeon. Теперь - двухпроцессорный ЧЕТЫРЕХЯДЕРНЫЙ Xeon. За счет увеличения числа ядер, реальная производительность выросла где-то раза в 2-2,5. В то же время - за последние 5 лет быстродействие дисковых массивов увеличилось, но наверное процентов на 30-40 примерно. Если тенденция сохранится - процессорная мощность будет намного дешевле чем дисковая. Учитывая что генерация плана запроса хорошо паралелиться - правильнее использовать литералы, а не bind-переменные.
|
|
03.08.2009, 19:00 | #8 |
MCITP
|
Цитата:
Сообщение от fed
....
3. Если поставить CURSOR_SHARING=EXACT, Oracle транслирует полученный запрос в select * from custTable where NLS_LOWER(Substr(custAccount,:bind1,:bind2)=NLS_LOWER(Substr(:bind3,:bind4,:bind5), после чего подставляет конкретные значения bind-переменных. Нетрудно догадаться, что левая часть сравнения перестает сопоставляться с выражением индекса и индекс перестает использоваться для исполнения запроса. ..... Было бы интересно ещё, как он поведёт себя с SIMILAR...
__________________
Zhirenkov Vitaly |
|
04.08.2009, 09:42 | #9 |
Moderator
|
Угу - конечно имелось в виду CURSOR_SHARING=FORCE
|
|
Теги |
oracle, курсор |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|