AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Администрирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 30.01.2015, 16:55   #1  
Akri is offline
Akri
Участник
 
23 / 10 (1) +
Регистрация: 16.08.2011
): Почему используется индекс (Oracle, DAX 2009)
Oracle, DAX 2009
С какого-то момента стала сильно задумываться рабочая аксапта на некоторых запросах – просто зависать минут на 5 – 20.

В качестве примера есть такой запрос, который запускается просто из джобика:

select firstonly RecId from SalesTable
where SalesTable.SalesId != "Заказ1" &&
SalesTable.CustAccount == "Клиент1" &&
SalesTable.RegionOrigSalesId == "123" ;

План запроса пишет такой:
SELECT /*+ INDEX(A I_366CUSTIDX) FIRST_ROWS */A.RECID
FROM SALESTABLE A
WHERE ((SUBSTR(NLS_LOWER(DATAAREAID),1,4)=NLS_LOWER(:IN1))
AND (((SUBSTR(NLS_LOWER(SALESID),1,20)<>NLS_LOWER(:IN2))
AND (SUBSTR(NLS_LOWER(CUSTACCOUNT),1,20)=NLS_LOWER(:IN3)))
AND (SUBSTR(NLS_LOWER(REGIONORIGSALESID),1,20)=NLS_LOWER(:IN4))))
Причем у нас есть тестовая конфигурация, на которой тот же самый запрос отрабатывает мгновенно (как и работало раньше на рабочей). На тесте план запроса такой:
SELECT /*+ FIRST_ROWS */A.RECID
FROM SALESTABLE A
WHERE ((SUBSTR(NLS_LOWER(DATAAREAID),1,4)=NLS_LOWER(:IN1))
AND (((SUBSTR(NLS_LOWER(SALESID),1,20)<>NLS_LOWER(:IN2))
AND (SUBSTR(NLS_LOWER(CUSTACCOUNT),1,20)=NLS_LOWER(:IN3)))
AND (SUBSTR(NLS_LOWER(REGIONORIGSALESID),1,20)=NLS_LOWER(:IN4))))
Много всего перерыли на эту тему. Сначала просто хочется понять в какую сторону копать – почему на рабочей базе используется индекс CustIdx (в него не входит REGIONORIGSALESID)?
Таблица SalesTable одинаковая на тесте и на рабочей (ну может быть только совсем немного отличаются данные).
Старый 30.01.2015, 18:02   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Вы процитировали не план запроса, а сам запрос.

Кстати, форма и джоб могут генерить разный запрос
Разница в хинтах

/*+ INDEX(A I_366CUSTIDX) FIRST_ROWS */
/*+ FIRST_ROWS */

Это влияет на то какой индекс выберет оптимизатор базы данных.

Поэтому нельзя непосредственно сравнивать запрос джоба и формы.
Старый 31.01.2015, 20:12   #3  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Не могу сказать про Оракл, но в MS SQL использование индекса CustIdx вполне оправдано (ну, конечно, если он получается селективным):
  • SalesId не может использоваться так как там неравенство.
  • CustAccount есть в CustIdx.
  • В общем случае, клиенты распределены в заказах достаточно равномерно.
В MS SQL различие можно было бы списать на статистику (возможно, что в одной из баз статистика устарела и движок некорректно определяет план запроса).
С точки зрения MS SQL смущает использование функции SUBSTR... В MS SQL такое бывает когда текстовые идентификаторы выровнены вправо (например, при переходе с Ax3.0 на следующую версию не была выполнена процедура реорганизации выравнивания). В MS SQL это приводит к очень серьезной деградации производительности, как в Оракле не знаю.
Старый 31.01.2015, 20:14   #4  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от Logger Посмотреть сообщение
Вы процитировали не план запроса, а сам запрос.
Не, в Oracle один из вариантов представления плана как раз не дерево решения (как в MS SQL), а только указание на использование индекса (подчеркну, что это только один из вариантов представления плана).
Старый 02.02.2015, 00:17   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
С точки зрения MS SQL смущает использование функции SUBSTR... В MS SQL это приводит к очень серьезной деградации производительности, как в Оракле не знаю.
В Оракле тоже, но это - by design и связано с тем, что до некоторых пор базы данных Oracle всегда были регистрозависимыми, а работать с регистронезависимым оракловыми collation'ами ядро AX 2009 специально отучили.
Старый 02.02.2015, 10:32   #6  
Akri is offline
Akri
Участник
 
23 / 10 (1) +
Регистрация: 16.08.2011
Провели эксперимент: сделали копию рабочего приложения и установили новый АОС (на другом компьютере), этим новым АОСом и копией приложения подключились к рабочей базе, запустили тот же джоб - работает мгновенно, план запроса как на тесте. Причина получается в АОСе рабочем или в компе, на котором АОС установлен - но в чем именно?
Старый 05.02.2015, 10:16   #7  
Akri is offline
Akri
Участник
 
23 / 10 (1) +
Регистрация: 16.08.2011
Обнаружилось, что на рабочих АОС-ах стояла галочка Allow INDEX hints in queries. Когда сняли эту галку, запрос из примера выше стал на рабочей конфигурации отрабатывать как на тесте – по тому же плану запроса (или как там это называется) и так же быстро.
Т.к. раньше на рабочей конфигурации все нормально работало без тормозов, то вопрос, поставил ли кто-то эту галку (что маловероятно) или какие-то другие условия привели к такому поведению индексов в совокупности с этой галкой, остался открытым – ну да ладно с ним!
Но на этом странности продолжились. Странности в непонятных тормозах в разных местах системы.
Например, стала тормозить разноска некоторых конкретных журналов – в журнале одна строка. Из дебагера стало понятно, что зависает на LedgerJournalTable.update(), когда система хочет проставить ledgerJournalTable.SystemBlocked = NoYes::Yes при разноске.
Т.е. такой джоб:
ttsbegin;
ledgerJournalTable = LedgerJournalTable::find("Журнал1", true);
ledgerJournalTable.SystemBlocked = NoYes::Yes;
ledgerJournalTable.update();
ttscommit;
всегда зависает на конкретном журнале «Журнал1», и всегда нормально отрабатывает на «Журнале2».

Куда копать? Что проверить-посмотреть-поэкспериментировать?
Старый 05.02.2015, 10:47   #8  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Поэкспериментировать с наймом Oracle DBA
За это сообщение автора поблагодарили: S.Kuskov (2).
Старый 05.02.2015, 13:20   #9  
AlexeyS is offline
AlexeyS
Участник
 
404 / 339 (12) ++++++
Регистрация: 15.06.2004
Адрес: москва
не знаю как в Oracle, но в MS SQL было пару раз, что появлялись непонятные тормоза на таблице и приходилось обновлять индекс, который "ломался", то есть при его использовании все разко замедлялось
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Prabhats: DAX 2009: Temporary Tables in Enterprise Portal Blog bot DAX Blogs 0 27.04.2011 11:11
Prabhats: DAX 2009 Enterprise Portal Development : Using the Ax Session Blog bot DAX Blogs 0 27.04.2011 11:11
msdynamicsax: DAX 2009 and MS SQL 2008 Blog bot DAX Blogs 0 09.08.2008 14:05
axStart: Microsoft Dynamics AX 2009 Hot Topics Web Seminar Series Blog bot DAX Blogs 0 06.08.2008 12:05
msdynamicsax: Enterprise Portal development in DAX 2009 Blog bot DAX Blogs 0 18.04.2008 07:06

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 15:31.