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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.11.2015, 17:06   #1  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
AX 2012 R2 CU7 Исправление медленно закрывающейся формы сопосталений проводок по клиенту/поставщику, открытой из журнала ГК
При помощи Tracing утилиты обнаружил в методе CustVendPaymNote.buildPaymNote() очень медленно выполняющийся запрос:

X++:
while select crossCompany RecId from specTrans
        order by specTrans.RecId
        where specTrans.SpecCompany == _specCompany
           && specTrans.SpecTableId == _specTableId
           && specTrans.SpecRecId   == _specRecId
        join RecId from custVendTransOpen
            where custVendTransOpen.DataAreaId == specTrans.RefCompany
               && custVendTransOpen.TableId == specTrans.RefTableId
               && custVendTransOpen.RecId   == specTrans.RefRecId
        join TransDate, DocumentNum, Invoice, PaymId, Voucher from custVendTrans
            where custVendTrans.RecId == custVendTransOpen.RefRecId

Выполнил его рефакторинг:

X++:
while select crossCompany TransDate, DocumentNum, Invoice, PaymId, Voucher
            from custVendTrans
            join RecId
            from custVendTransOpen
           where custVendTransOpen.RefRecId == custVendTrans.RecId
            join RecId
            from specTrans
           where specTrans.RefCompany       == custVendTransOpen.DataAreaId
              && specTrans.RefTableId       == custVendTransOpen.TableId
              && specTrans.RefRecId         == custVendTransOpen.RecId
              && specTrans.SpecCompany      == _specCompany
              && specTrans.SpecTableId      == _specTableId
              && specTrans.SpecRecId        == _specRecId

И создал на таблице SpecTrans индекс:

X++:
#SpecTransIdx
      PROPERTIES
        Name                #SpecTransIdx
      ENDPROPERTIES
      
      INDEXFIELDS
        #SpecRecId
        #SpecTableId
        #SpecCompany
        #Partition
        #RecId
        #INCLUDEDCOLUMNPRESENT
        #RefRecId
        #INCLUDEDCOLUMNPRESENT
        #RefTableId
        #INCLUDEDCOLUMNPRESENT
        #RefCompany
        #INCLUDEDCOLUMNPRESENT
      ENDINDEXFIELDS

До рефакторинга запрос выполнялся 12 сек, после - меньше 1 сек. Пролем в работе бизнес-логики пока не обнаружил.
За это сообщение автора поблагодарили: Logger (3), plumbum (2).
Старый 24.11.2015, 17:34   #2  
GannexMan is offline
GannexMan
Участник
 
5 / 13 (1) ++
Регистрация: 07.06.2006
Хотел бы уточнить некот. аспекты.
1.За счет чего получился более быстрый запрос? (Происходил скан таблиц или оптимизатор SQL сбоил?)
2.Размер индекса может быть равным самим данным и больше(с включением полей прямо в индекс), что для вставки и обновлений тоже не очень.
3.Кол-во записей во всех талицах?
4.План запроса увидеть бы до и после.(Сколько записей ожидается, сколько обработано и т.п.)

Последний раз редактировалось GannexMan; 24.11.2015 в 17:36.
Старый 24.11.2015, 19:11   #3  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Это текст и план стандартного SQL зароса (новый индекс не отключал, т.к. на план выполнения он не повлиял):

X++:
SELECT T1.RECID,
	T2.RECID,
	T2.DATAAREAID,
	T3.TRANSDATE,
	T3.DOCUMENTNUM,
	T3.INVOICE,
	T3.PAYMID,
	T3.VOUCHER,
	T3.DATAAREAID,
	T3.RECID 
FROM SPECTRANS T1 CROSS 
JOIN VENDTRANSOPEN T2 CROSS 
JOIN VENDTRANS T3 
WHERE ((T1.PARTITION=5637144576) 
	AND (((T1.SPECCOMPANY='DA1') 
	AND (T1.SPECTABLEID=212)) 
	AND (T1.SPECRECID=17852886295))) 
	AND ((T2.PARTITION=5637144576) 
	AND (((T2.DATAAREAID=T1.REFCOMPANY) 
	AND (T1.REFTABLEID=866)) 
	AND (T2.RECID=T1.REFRECID))) 
	AND ((T3.PARTITION=5637144576) 
	AND (T3.RECID=T2.REFRECID 
	AND (T3.DATAAREAID = T2.DATAAREAID) 
	AND (T3.PARTITION = T2.PARTITION))) 
	ORDER BY T1.RECID
Нажмите на изображение для увеличения
Название: ExecPlan1.JPG
Просмотров: 463
Размер:	31.7 Кб
ID:	9434

А это текст и план отрефакторенного SQL зароса:

X++:
SELECT T1.TRANSDATE,
       T1.DOCUMENTNUM,
       T1.INVOICE,
       T1.PAYMID,
       T1.VOUCHER,
       T1.RECID,
       T2.RECID,
       T3.RECID
  FROM VENDTRANS T1 CROSS
  JOIN VENDTRANSOPEN T2 CROSS
  JOIN SPECTRANS T3
 WHERE ((T1.PARTITION=5637144576)
   AND (T1.DATAAREAID='DA1'))
   AND (((T2.PARTITION=5637144576)
   AND (T2.DATAAREAID='DA1'))
   AND (T2.REFRECID=T1.RECID))
   AND ((T3.PARTITION=5637144576)
   AND ((((((T3.REFCOMPANY=T2.DATAAREAID)
   AND (T3.REFTABLEID=866))
   AND (T3.REFRECID=T2.RECID))
   AND (T3.SPECCOMPANY='DA1'))
   AND (T3.SPECTABLEID=212))
   AND (T3.SPECRECID=17852886295)))
Нажмите на изображение для увеличения
Название: ExecPlan2.JPG
Просмотров: 263
Размер:	46.2 Кб
ID:	9435
Старый 24.11.2015, 20:57   #4  
GannexMan is offline
GannexMan
Участник
 
5 / 13 (1) ++
Регистрация: 07.06.2006
Думаю, что план запроса лучше не стал.
Если в первом варианте, было два кластерных индекса,
то во втором только один.
Получили Key Lookup и жесткий удар по производительности.

Во втором случае одна и та же таблица VendTrans выдала разное кол-во записей.
В последнем запросе явно указано для всех таблиц данные брать только из DA1, возможно это и объясняет поведение, оптимизатор ограничил кол-во записей по выбранной компании, а не по всем

AND (T3.RECID=T2.REFRECID
AND (T3.DATAAREAID = T2.DATAAREAID)
AND (T3.PARTITION = T2.PARTITION)))

Судя по тому, как был написан первоначальный запрос,
складывается впечатление, что его "выгибали" так специально.

Если, ограничить VendTrans явным указанием DATAAREAID,
оригинальный запрос будет намного быстрей.

Последний раз редактировалось GannexMan; 24.11.2015 в 21:02.
За это сообщение автора поблагодарили: Morpheus (3).
Старый 25.11.2015, 11:27   #5  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Цитата:
Сообщение от GannexMan Посмотреть сообщение
Получили Key Lookup и жесткий удар по производительности.
Key Lookup можно устранить, добавив IncludedColumn(s) поля в индекс.

Коллеги, у вас есть возможность проверить на ваших инсталляциях, быстро ли закрывается форма сопоставлений? Для теста необходимо создать в журнал ГК транзакцию платеж для клиента или поставщика и сопоставить ее с инвойсом при помощи меню Функции/Сопоставление на форме строк журнала ГК. После сопоставления закрыть форму и оценить, как быстро она закроется.
Старый 25.11.2015, 11:44   #6  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Коллеги, у вас есть возможность проверить на ваших инсталляциях, быстро ли закрывается форма сопоставлений?
У меня на CU7 - быстро (DATAAREAIDLITERAL и PARTITIONLITERAL - включены)
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: Morpheus (3).
Старый 25.11.2015, 08:10   #7  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Выполнил его рефакторинг
А отключение (если трасса была собрана верно) crosscompany было запланировано или это побочный эффект ? Просто помимо него и отключения дурацкой и ненужной сортировки по SpecTrans.RecId - никаких изменений в коде нет
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.11.2015, 11:12   #8  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Цитата:
Сообщение от Vadik Посмотреть сообщение
А отключение (если трасса была собрана верно) crosscompany было запланировано или это побочный эффект ?
Где Вы видите, что crosscompany отключен?

Цитата:
Сообщение от Vadik Посмотреть сообщение
Просто помимо него и отключения дурацкой и ненужной сортировки по SpecTrans.RecId - никаких изменений в коде нет
Порядок, в котором следуют таблицы, изменен. В итоге sql запрос изменился.
Старый 25.11.2015, 11:38   #9  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Где Вы видите, что crosscompany отключен?
Ну давайте вместе посчитаем в трассах количество критериев WHERE по DATAAREAID на VENDTRANS и VENDTRANSOPEN. У меня получилось 0 до рефакторинга и 2 - после
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.11.2015, 12:09   #10  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Нашел еще один похожий "медленный" запрос в методе LedgerJournalTransUpdateVend.checkSettleVoucher(), который вызывается при проверке/разноске журнала ГК содержащем сопоставленные проводки по клиенту или поставщику:

X++:
while select crossCompany RecId from specTrans
            where specTrans.SpecCompany == _ledgerJournalTrans.company() &&
                specTrans.SpecTableId == _ledgerJournalTrans.TableId &&
                specTrans.SpecRecId == _ledgerJournalTrans.RecId
            join RecId from vendTransOpen
                where specTrans.RefCompany == vendTransOpen.DataAreaId &&
                    specTrans.RefTableId == vendTransOpen.TableId &&
                    specTrans.RefRecId == vendTransOpen.RecId
            join  RecId, AccountNum, Voucher, Approved, Closed from vendTrans
                where vendTransOpen.RefRecId == vendTrans.RecId
            join Party from vendTransVendor
                where vendTrans.AccountNum == vendTransVendor.AccountNum
Куда копать?
Старый 25.11.2015, 14:49   #11  
GannexMan is offline
GannexMan
Участник
 
5 / 13 (1) ++
Регистрация: 07.06.2006
@ZVV
Оба запроса - кросс компани.
В первом через промежуточное условие и во втром,
аксапта "вот так решила" сгенерировать запрос.
В коде указано для каких компаний надо делать выборку, вот аксапта и указала явно.
Видно не смогла "связать" условием как в первом варианте и стала перечислять компании.

@Morpheus Куда копать?
Сначала в план запроса. Смотрим, где макс. поток данных и пытаемся его ограничить.

Последний раз редактировалось GannexMan; 25.11.2015 в 15:01.
Старый 25.11.2015, 15:07   #12  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от GannexMan Посмотреть сообщение
Оба запроса - кросс компани.
В первом через промежуточное условие и во втром,
Мне видится что вы не правы.
В первом запросе нет никакого ограничения на SPECTRANS.REFCOMPANY, ни явно, ни через условия. Т.е. оно может быть любым и ссылаться на записи VendTrans(Open) в любой компании.
Во втором же запросе неожиданно появляются эти явные ограничения T1/T2.DATAAREAID='DA1'
__________________
Zhirenkov Vitaly
Старый 25.11.2015, 15:20   #13  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от ZVV Посмотреть сообщение
Мне видится что вы не правыT1/T2.DATAAREAID='DA1'
Не-не-не, там все интересно. В оригинальном запросе фактически делается JOIN VendTrans с VendTransOpen
X++:
AND (T3.DATAAREAID = T2.DATAAREAID) 
AND (T3.PARTITION = T2.PARTITION)
а в измененном - фильтрация
X++:
((T1.PARTITION=5637144576)
AND (T1.DATAAREAID='DA1'))
AND (((T2.PARTITION=5637144576)
AND (T2.DATAAREAID='DA1'))
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.11.2015, 15:27   #14  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Vadik Посмотреть сообщение
Не-не-не, там все интересно. В оригинальном запросе фактически делается JOIN VendTrans с VendTransOpen
а в измененном - фильтрация
да
но с чего он решил, что нужно только 'DA1' остаётся непонятным?

если только автор привёл не все данные и это только "частичный" запрос по одной из компаний...
не знаю умеет ли Аксапта так делать, но с чисто логической точки зрения после убирания сортировки это могло бы иметь некоторый смысл с точки зрения оптимизации...
__________________
Zhirenkov Vitaly
Старый 25.11.2015, 15:40   #15  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от ZVV Посмотреть сообщение
да
но с чего он решил, что нужно только 'DA1' остаётся непонятным?
Очень похоже на косяк, потому что не должно было такого произойти - фильтр на SpecTrans.SpecCompany, а JOIN по RefCompany

Надо будет потестировать, мы тоже на CU7
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.11.2015, 15:27   #16  
GannexMan is offline
GannexMan
Участник
 
5 / 13 (1) ++
Регистрация: 07.06.2006
Цитата:
Сообщение от ZVV Посмотреть сообщение
Мне видится что вы не правы.
В первом запросе нет никакого ограничения на SPECTRANS.REFCOMPANY, ни явно, ни через условия. Т.е. оно может быть любым и ссылаться на записи VendTrans(Open) в любой компании.
Во втором же запросе неожиданно появляются эти явные ограничения T1/T2.DATAAREAID='DA1'
Название: 2015-11-25_1425.png
Просмотров: 793

Размер: 40.0 Кб



Последний раз редактировалось GannexMan; 25.11.2015 в 15:29.
Старый 25.11.2015, 15:46   #17  
Morpheus is offline
Morpheus
Участник
Аватар для Morpheus
Соотечественники
 
602 / 167 (7) ++++++
Регистрация: 30.03.2005
Адрес: Київ-København-Düsseldorf
Цитата:
Сообщение от ZVV Посмотреть сообщение
Во втором же запросе неожиданно появляются эти явные ограничения T1/T2.DATAAREAID='DA1'
Второй запрос получил следующим образом

X++:
select generateonly table...;
info(table.getSQLStatement());
В него вместо знаков ? подставил значения.
Старый 25.11.2015, 15:50   #18  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
Цитата:
Сообщение от Morpheus Посмотреть сообщение
Второй запрос получил следующим образом

X++:
select generateonly table...;
info(table.getSQLStatement());
В него вместо знаков ? подставил значения.
Лучше б конечно протрэйсить, чтоб наверняка...
__________________
Zhirenkov Vitaly
Теги
ax2012r2, performance, slow, тормоза

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
kurthatlevik: SYNC for AX 2012 R2 CU7 Blog bot DAX Blogs 0 08.11.2013 21:11
emeadaxsupport: New and updated content is available for cumulative update 6 for Microsoft Dynamics AX 2012 R2 Blog bot DAX Blogs 0 27.06.2013 19:11
amer-ax: It was a great day! Blog bot DAX Blogs 3 29.12.2012 01:02
daxdilip: Whats New in Dynamics AX 2012 (A brief extract from the recently held Tech Conf.) Blog bot DAX Blogs 7 31.01.2011 12:35
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

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

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

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