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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.11.2005, 17:43   #1  
axaLearner is offline
axaLearner
Участник
 
88 / 17 (1) ++
Регистрация: 24.06.2004
Адрес: God knows
find() vs. join
Возник вопрос: что производительнее
while select purchLine
{
inventTable = InventTable::find(PurchLine.itemId);
some action;
}
или
while select purchLine
join inventTable
where purchLine.ItemId == inventTable.ItemId
{
some action
}

?
Старый 24.11.2005, 18:08   #2  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,322 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
гым... ну если нет никаких подводных камней - то по идее - первый вариант по определению дольше; существенно дольше. Связано это с тем что во втором случае исполняется один SQL-запрос, а в первом - по кол-ву записей в purchTable. А вообще-то есть профайлер - он более точно даст ответ.
В частности аналогичная ситуация в Transact-SQL для SQL Server однозначно решается в пользу второго варианта.

По сути - почему народ часто переписывает какие-л закрытия или пересчеты - потому что в Аксапте исключение дублирования кода и облегчение дальнейшего сопровождения зачастую идет в ущерб производительности. И дело не столько в Аксапте - сколько в том, что не все можно соптимизировать и при этом написать общий код на все случаи жизни.
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 24.11.2005 в 18:12.
Старый 24.11.2005, 18:35   #3  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
а кеширование?
Старый 24.11.2005, 19:04   #4  
vic_z is offline
vic_z
Участник
 
26 / 30 (2) +++
Регистрация: 11.12.2003
Цитата:
Сообщение от belugin
а кеширование?
Так в кеше тоже надо сначала найти нужную запись, что тоже не на пользу производительности. А в случае join система будет только с одним курсором работать.
Да и не всегда возможно InventTable закешировать.
Старый 24.11.2005, 23:40   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от axaLearner
Возник вопрос: что производительнее
while select purchLine
{
inventTable = InventTable::find(PurchLine.itemId);
some action;
}
или
while select purchLine
join inventTable
where purchLine.ItemId == inventTable.ItemId
{
some action
}

?
В общем случае второй вариант.

Но зачастую - первый. Тут правильно говорили о кэшировании.

Но не только кэширование. Вы привели только один дополнительный поиск - номенклатуру. По строке закупке можно многое чего искать дополнительно. И название склада, и параметры парти, прочие складские аналитики и финансовые, дополнительные параметры для лота возврата, искать складские проводки с лотом и т.п.

Т.е. правильно вопрос выглядит так:
что лучше
X++:
while select purchLine
{
    inventTable = InventTable::find(PurchLine.itemId);
    some action;
    if( some1 ) someTable1::find(PurchLine.someId1);
    if( some2 ) someTable2::find(PurchLine.someId2);
    if( some3 ) someTable3::find(PurchLine.someId3);
    ...
}
или
X++:
while select purchLine 
                   join inventTable
                   where purchLine.ItemId == inventTable.ItemId
                   join someTable1
                   where purchLine.someId1 == someTable1.someId
                   join someTable2
                   where purchLine.someId2 == someTable2.someId
                   join someTable3
                   where purchLine.someId3 == someTable3.someId
                   ...
{
    some action
}
А здесь ответ уже далеко не однозначен.

По идее надо бы еще говорить о плане запроса и о кэшировании запросов на СКЛ... О том, насколько лучше СКЛ оптимизирует простые запросы (даже если их много) по сравнению со сложными (но редкими).

Кроме этих соображений есть еще одно - только первый вариант позволит сделать универсальный и развесистый код. Только первый вариант позволит скрыть детали реализации.

Вы пишете свой метод для работы с номенклатурой внутри цикла по строкам закупки. Ваш метод получает в качестве параметра код номенклатуры. Как эту номенклатуру получили вас в вашем методе не волнует. Ваш метод занимается только своей работой. В таком случае бывает удобнее внутри вашего метода сделать лишний find.
__________________
полезное на axForum, github, vk, coub.
Старый 25.11.2005, 10:59   #6  
axaLearner is offline
axaLearner
Участник
 
88 / 17 (1) ++
Регистрация: 24.06.2004
Адрес: God knows
Всем спасибо, вцелом все прояснилось, для конкретных же случаев без профайлера, похоже, не обойтись.
Старый 26.11.2005, 15:36   #7  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Цитата:
Сообщение от otkudao
если Вы не "системщик" в Аксапте, а "прикладник", т.е. пишете на слое cus-usr, то универсальность в ущерб производительности НЕДОПУСТИМАЯ роскошь.
Не согласен с такой формулировкой. Во-первых, тот факт, что Вы пишете на слое CUS или USR не освобождает Вас от ответственности за написанные Вами модификации. Следовательно Вы всегда должны представлять, какое развитие может получить создаваемая Вами функциональность, и оставлять возможность для этого развития. Во-вторых, практически любое решение представляет собой компромисс между производительностью и универсальностью.

Цитата:
Сообщение от otkudao
Указанные запрос - не супер сложный. Кроме того, медленные предикаты СКЛя Аксапта попросту не пропускает (хэвинг), если мне не изменяет память.
Правильнее говорить не "не пропускает", а "не использует при интерпретации". Да и не "долгие" инструкции она не пропускает, а "не универсальные" .

Цитата:
Сообщение от otkudao
Т.е. супер-сложный-долгий запрос у Вас создать не получится.
Нет ничего невозможного

Цитата:
Сообщение от otkudao
Мало того, берусь утверждать, что самое скромное кол-во простых запросов взамен сложного по тому же результату будет НА ПОРЯДКИ дольше в исполнении-получении.
Простое сравнение, однако, не имеет практической ценности. Всегда надо исходить из контекста конкретной задачи.

Цитата:
Сообщение от otkudao
...подтверждено пунктом 1 раздела Оптимизация Бест практис.
А вот это очень правильное замечание. Согласно BP, сервер БД - наиболее приоритетное место для выполнения бизнес-логики. Другими словами, если у Вас есть возможность в Вашей задаче использовать СУБД, не нарушая при этом других принципов разработки в Axapta, предпочтение следует отдавать именно этому варианту. В большинстве случаев это, правда, касается использования массовых обновлений данных и выборок с агрегирующими функциями.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Проблемы с Exists Join Logger DAX: Программирование 28 28.04.2010 02:54
daxmy: AOT Find function Blog bot DAX Blogs 0 17.08.2007 01:23
Глюки в Query с разными типами Join (в т.ч. NonExistsJoin) к одной таблице gl00mie DAX: Программирование 10 14.02.2007 13:22
Dynamics AX Geek: cross-references & find Blog bot DAX Blogs 0 28.10.2006 16:40

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

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

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