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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 26.02.2016, 19:16   #1  
Blog bot is offline
Blog bot
Участник
 
25,475 / 846 (79) +++++++
Регистрация: 28.10.2006
mfp: InventDim in AX7
Источник: http://blogs.msdn.com/b/mfp/archive/...im-in-ax7.aspx
==============
Background

The way a new inventory dimension is added in AX has not changed significantly for several releases. Even for AX 7 the best guide is still chapter 6 in Inside Dynamics AX 4.

In AX 2012 we almost hit a SQL limitation on the maximum number of fields in the DimIdx index (the limit is 16) – preventing you from adding more dimensions. To address this, we added a hashing function in R2 to ensure uniqueness – and a configuration key (InventDimExtensibility) to enable/disable the overhead of hashing. This is described here: Walkthrough: More than 14 InventDim Dimensions Despite Index Limit [AX 2012] and Avoid index length issues with InventDim

In AX 2012 R3 the limit is exceeded out of the box. This means that everyone running warehouse was paying the hashing overhead – measured to be about 10% performance degradation. To compensate, we wrote a guide on how to avoid the hashing by disabling other inventory dimensions not needed, like serial numbers or Russian dimensions. This required code changes and thus increased TCO to gain performance. The guide is available here: Microsoft Dynamics AX R3 – New Warehouse Management solutions impact on InventDim extensibility and migration scenarios

What changed in AX7?

As you can probably see from above, the InventDim story has grown quite complex. In AX7 this stopped. The solution is simpler and faster.

Issue 1 – Performance

In AX 2012 the hashing value is stored in a container. Container types are relatively expensive is SQL, as they are stored in a column of type varbinary(100). The container type in X++ is also quite expensive, as there is no native IL representation for it. Every reference results in an interop call to the native platform. (aka. Speed of sound).

Solution

Store the hash in a string instead – hex encoded. 40 characters is enough to contain the hash. String is a native type in IL – much much faster than containers. In SQL the type for the hashing column became nvarchar(40) – also a bit lighter than varbinary(100).



Issue 2 – Complexity

In AX 2012 R3 you need to consider the max number of fields in an index – if you don't need all the dimensions provided out-of-the-box, you should reshuffle the index to avoid enabling the InventDimExtensibility configuration key. If you truly needed all of the dimensions you paid the performance overhead.

Solution

Simply just hash all the dimensions. This allows us to deprecated the InventDimExtensibility configuration key. In AX7 all code runs as IL – the price of hashing is insignificant. You no longer need to even consider reshuffling indexes or hashes. In other words, we deleted a bunch of code – and you can focus on more valuable things.

Issue 3 – SQL footprint

In AX 2012 each dimension was stored 3 times in SQL. One time for the actual column, one time in an index for the dimension, and one time in the big index ensuring uniqueness across dimensions.

Solution

Given the hash string is enough to guarantee uniqueness, we don't need the big index anymore – we just need a unique index on the hash string. Now, the index guaranteeing uniqueness only contains 3 fields: PartionId, DataAreaId and SHA1HashHex. This reduced the SQL footprint from 2kb to 1.3kb per row – or about 30%.

Did it help?

Yes, the performance improved significantly. The chart below compares the performance of the InventDim::findOrCreate() method in AX7 before (with InventDimExtensibility ON/OFF) and after this change. Even when always hashing all dimensions we are 40% faster compared to the old system with no hashing.



And, you don't have to change the InventDim table again – unless you are adding a new dimension.

When adding a new dimension(s) you must:

  1. Include them in the hashKey() method on the InventDim table. Doing so is fairly simple, and it doesn't require rehashing of existing records. Just include the following lines for each new dimension:
    str valueMyNewDimension = strRTrim(this.MyNewDimension);  
    if (valueMyNewDimension) 
    {  


        hashKey += 'MyNewDimension:' + valueMyNewDimension + '~';  
    }  


     
  2. Consider if you have the correct covering indexes. If not, make sure to create the index(es) you need. Usually, a non-unique index per dimension will satisfy requirements.
 

THIS POST APPLIES TO MICROSOFT DYNAMICS AX7 TECHNICAL PREVIEW; IS PROVIDED AS-IS AND CONFERS NO RIGHTS.




==============
Источник: http://blogs.msdn.com/b/mfp/archive/...im-in-ax7.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
За это сообщение автора поблагодарили: alex55 (1).
Старый 26.02.2016, 22:46   #2  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Вот это поворот!.. Для 2012-й такое штатно наверняка не сделают, но это не беда - можно и самостоятельно такое реализовать. Мне лично другое непонятно: нафига было использовать SHA1 cо 160-битным значением, которое потом пихать в контейнер, контейнер - в varbinary(100), иметь все эти проблемы с производительностью и размером записей таблицы... Ведь можно было использовать MD5 со 128-битным значением, которое прекрасно помещается в родной для SQL тип uniqueidentifier с бинарным представлением "под капотом" и удобным строковым представлением в запросах.
За это сообщение автора поблагодарили: mazzy (2), Logger (5), MikeR (3).
Старый 27.02.2016, 11:19   #3  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Мне лично другое непонятно:
Можно спросить у автора поста в его комментах.
Старый 27.02.2016, 16:00   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Может дело было в скорости генерации значений. Все равно mfp все свел к строкам. Вряд ли они сильно проигрывают гуидам. Ну если только из за объема памяти на хранение.

Хэш функции Why?
Старый 27.02.2016, 22:37   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Logger Посмотреть сообщение
Может дело было в скорости генерации значений.
Это не так - MD5 быстрее.
Цитата:
Сообщение от Logger Посмотреть сообщение
Все равно mfp все свел к строкам. Вряд ли они сильно проигрывают гуидам. Ну если только из за объема памяти на хранение.
GUID - это 16 байт, значения сравниваются бинарно, SHA1 в строковом представлении - это 80 байт (40 символов unicode для hex-представления 160-битного значение), сравнение регистронезависимое, т.е. надо постоянно приводить сравниваемые значения к верхнему или нижнему регистру с учетом collation'а базы данных.
Старый 28.02.2016, 09:40   #6  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Да, точно, про издержки на сравнение я и забыл.
Ну, аргументов в пользу sha1 не осталось.
Кроме меньшей вероятности коллизий. Видимо это и было основным соображением.
Старый 28.02.2016, 12:54   #7  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Автор говорит, что 160 бит конвертируются в строку nvarchar(40), длиной 80 байт, т.е. 640 бит, т.е. в ЧЕТЫРЕ раза больше (два символа на байт при конвертации в строковое hex представление, и два байта на символ при хранении в БД). Расточительно, не находите?
__________________
Axapta non erubescit
Старый 28.02.2016, 17:21   #8  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Да, пожалуй расточительно.
Старый 29.02.2016, 09:17   #9  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Вообще конечно хотелось бы увидеть, сколько времени метод InventDim::findOrCreate() занимает при разноске какого-нибудь журнала или заказа в процентах. т.е. если это будет число порядка 0.01% от всей времени разноски, то оптимизация конечно мега-важна и необходима
За это сообщение автора поблагодарили: Vadik (1).
Старый 29.02.2016, 11:33   #10  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от trud Посмотреть сообщение
Вообще конечно хотелось бы увидеть, сколько времени метод InventDim::findOrCreate() занимает при разноске какого-нибудь журнала или заказа в процентах. т.е. если это будет число порядка 0.01% от всей времени разноски, то оптимизация конечно мега-важна и необходима
Так запустите разноску с trace parser'ом и скажите нам
Старый 29.02.2016, 12:05   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
У меня тут совершенно случайно завалялась трассировка разноски на тестовом сервере розничного журнала операций (RetailStatementTable), в ходе которой создается и разносится заказ на продажу:
  • Заказ на продажу вышел в 127 строк (по крайней мере, в разноске накладной postInventory() вызывался именно столько раз)
  • InventDim::findOrCreate() вызывался 2205 раз, total inclusive time 784 ms, total exclusive 153 ms, total database time 10.7 ms
  • Общее время разноски 306054 ms, т.е. чуть больше 5 минут.
За это сообщение автора поблагодарили: Ruff (2).
Старый 29.02.2016, 13:34   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Спасибо, очень интересно.


Цитата:
Сообщение от gl00mie Посмотреть сообщение
  • InventDim::findOrCreate() вызывался 2205 раз, total inclusive time 784 ms, total exclusive 153 ms, total database time 10.7 ms
total inclusive time - 784 ms - время БД составило 1,4 % ( 10.7 / 784 )
total exclusive time - 153 ms - время БД составило 7,4 % ( 10.7 / 153 )

Не маловато ли ?
Куда же делось остальное время ? Неужели хеш считался ? (т.е. мы на него потеряли больше 90 % времени вызова InventDim::findOrCreate() )

Последний раз редактировалось Logger; 29.02.2016 в 13:54.
Старый 29.02.2016, 14:02   #13  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Для приведенных 2205 вызовов InventDim::findOrCreate() было лишь 4 обращения к БД (total database calls), остальные запросы была обработаны из кэша таблицы InventDim на АОСе.
Старый 01.03.2016, 18:43   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от belugin Посмотреть сообщение
Можно спросить у автора поста в его комментах.
Автор в комментариях ответил, что использование MD5 в продуктах Microsoft запрещено по соображениям безопасности (алгоритм "взломан" на предмет поиска коллизий), хотя непонятно, какое это отношение имеет к индексированию переменного числа полей в InventDim. В общем, добавить какую-нить #pragma warning для отключения предупреждений компилятора люди могут, а аналогично отключить проверку на использование "небезопаносной" MD5 там, где о криптографии и речи не идет, - видимо, не могут, поэтому и решили мучиться с SHA1, контейнерами, varbinary(100), hex-строками и проч. "Сами создаем себе трудности и сами их героически преодолеваем"
За это сообщение автора поблагодарили: mazzy (2), S.Kuskov (2).
Старый 01.03.2016, 19:55   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от b_nosoff Посмотреть сообщение
Автор говорит, что 160 бит конвертируются в строку nvarchar(40), длиной 80 байт, т.е. 640 бит, т.е. в ЧЕТЫРЕ раза больше (два символа на байт при конвертации в строковое hex представление, и два байта на символ при хранении в БД). Расточительно, не находите?
Возможно проще было бы 20 байт хеш значения порезать на 16 и 4 байта. И один кусок кодировать как guid поле SHA1HashGuid, а другой как int32 поле SHA1HashInt32. Все равно индекс составной (SHA1HashHex, dataareaid, partitionid) так что где 3 поля там и 4, зато по объему выиграем сильно.

Вариант 1
SHA1HashHex, dataareaid, partitionid это 80 + 8 + 8 = 96 байт

Вариант 2
SHA1HashIntGuid, SHA1HashInt32, dataareaid, partitionid это 16 + 4 + 8 + 8 = 36 байт

Выигрыш по объему - 62 %
Больше чем в 2,5 раза.
За это сообщение автора поблагодарили: mazzy (2).
Старый 02.03.2016, 21:40   #16  
lvan is offline
lvan
Участник
Аватар для lvan
Лучший по профессии 2014
 
856 / 82 (4) ++++
Регистрация: 15.04.2011
Записей в блоге: 1
на современных процах sha1 уже давно считается быстро
специальные команды же сделали
За это сообщение автора поблагодарили: Logger (1).
Старый 03.03.2016, 18:19   #17  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
672 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Заказ на продажу вышел в 127 строк
InventDim::findOrCreate() вызывался 2205 раз
есть где развернуться оптимизаторам кода!
__________________
Felix nihil admirari
Старый 03.03.2016, 18:58   #18  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Не может ли такого быть, что есть какая-то другой сценарий, который требует больше операций с inventdim?
Старый 03.03.2016, 20:46   #19  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,874 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от belugin Посмотреть сообщение
Не может ли такого быть, что есть какая-то другой сценарий, который требует больше операций с inventdim?
Наверняка. И что тогда ?
Старый 03.03.2016, 21:06   #20  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Logger Посмотреть сообщение
Наверняка. И что тогда ?
Итогдаааа... Использовать этот сценарий для оценки качества оптимизации
Теги
ax2012, ax7, hash, inventdim, md5, sha1, ax2012r3

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
mfp: What is new in X++ in AX7? Blog bot DAX Blogs 2 10.02.2016 00:29
mfp: X++ in AX7: Garbage Collection Blog bot DAX Blogs 0 21.12.2015 11:11
mfp: X++ in AX7: Const keyword Blog bot DAX Blogs 0 17.12.2015 12:02
mfp: X++ in AX7: Static event subscription Blog bot DAX Blogs 0 11.12.2015 11:11
mfp: X++ in AX7 Blog bot DAX Blogs 0 02.12.2015 22:13

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 12:56.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.