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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.06.2011, 11:23   #1  
Katuxa is offline
Katuxa
Участник
 
36 / 10 (1) +
Регистрация: 13.05.2011
Оптимизация работы функции
Всем добрый день!
Помогите пожалуйста решить одну проблему.
Есть таблица параметров объектов ЖКХ и есть таблица значений параметров для объектов ЖКХ. Нужно в параметрах по нажатию на кнопку занести все параметры, (которые есть в таблице параметров) в таблицу значений параметров для каждого объекта ЖКХ.
Написала следующую функцию:
X++:
static server void AcceptChanges()
{
  HCSBuildParam buildParam;
  HCSBuildParamValue paramValue;
  HCSBuildTable buildTable;
  int i;

  ttsbegin;
  while select BuildCode from buildTable
  {
    while select buildParam
   {
    select ParamCode from paramValue where paramValue.BuildCode == buildTable.BuildCode
                                        && paramValue.ParamCode == buildParam.ParamCode;
    if (!paramValue)
    {
     paramValue.BuildCode = buildTable.BuildCode;
     paramValue.ParamCode = buildParam.ParamCode;
     paramValue.insert();
    }
   }
  }
  ttscommit;
}
Она отрабатывает правильно, но по времени где-то 2-3 минуты. Может как-то можно по-другому написать, чтобы быстрее отрабатывало.
Старый 06.06.2011, 11:32   #2  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,690 / 405 (17) +++++++
Регистрация: 23.03.2006
а чем не устраивает время 2-3 минуты? это такая частая опепация внутри другой, что вам так необходима оптимизация?
для оптимизации добавьте во второй цикл notexists join paramValue

Последний раз редактировалось ice; 06.06.2011 в 11:37.
Старый 06.06.2011, 11:35   #3  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
Ну во первых скажите спасибо тому, кто у вас придумал такую структуру данных
Я вижу два решения:
1. Организовать "правильную" структуру, сделать в нее импорт данных и пользоваться.
2. Оставить все как есть, но переписать с использованием RecordInsertList. Не факт что все залетает, но должно быть быстрее.
За это сообщение автора поблагодарили: mazzy (2).
Старый 06.06.2011, 11:38   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Katuxa Посмотреть сообщение
Она отрабатывает правильно, но по времени где-то 2-3 минуты.
попробую произнести на русском языке то, что вы написали

================
для каждой записи из buildTable
выбрать ВСЕ (!) записи из buildParam // в результате buildParm полностью перебирается столько раз сколько записей в buildTable

если нет записи в paramValue для комбинации buildTable, buildParam
то добавить в paramValue
================

во-первых, вы точно хотели выбирать ВСЕ возможные комбинации из buildTable, buildParam?
может эта пара у вас как-то связана?

во-вторых, у вас делается куча вложенных маленьких запросов внутри цикла.
по сути дела SQL-сервер захлебывается (ddos'ится).

попробуйте объединить запросы в один.
если логика правильна, то примерно так:
X++:
ttsbegin;
  while select BuildCode from buildTable
  join buildParam
  not exists join ParamCode from paramValue where paramValue.BuildCode == buildTable.BuildCode
                                        && paramValue.ParamCode == buildParam.ParamCode;
  {
     paramValue.BuildCode = buildTable.BuildCode;
     paramValue.ParamCode = buildParam.ParamCode;
     paramValue.insert();
  }
  ttscommit;
обратите внимание, что в этом случае запрос на SQL-сервер посылается один раз.
SQL-сервер один раз обрабатывает этот более сложный запрос вместо кучи маленьких.
далее мы от него получаем результаты один раз, а не внутри цикла.
накладных расходов меньше. profit.

будьте внимательны с not exists join в Аксапте (поищите на форуме, обсуждалось)
__________________
полезное на axForum, github, vk, coub.
Старый 06.06.2011, 11:41   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от _scorp_ Посмотреть сообщение
2. Оставить все как есть, но переписать с использованием RecordInsertList. Не факт что все залетает, но должно быть быстрее.
да. и это тоже.
__________________
полезное на axForum, github, vk, coub.
Старый 06.06.2011, 11:59   #6  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,895 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Ну и в качестве окончательной оптимизации, если вы используете DAX 2009, можно попробовать:
X++:
ttsbegin;
  insert_recordset paramValue2(BuildCode,ParamCode)
  select BuildCode from buildTable
  join paramCode from buildParam
  not exists join ParamCode from paramValue where paramValue.BuildCode ==     buildTable.BuildCode
    && paramValue.ParamCode == buildParam.ParamCode;
ttscommit;
Обрабатывается всего в две операции с БД. Одна -селект во временную таблицу, вторая - вставка из временной таблицы в постоянную, с выделением recId.
Да - если у вас переопределен insert() на paramValue, то особого убыстрения не случится, поскольку в этом случае, все будет выполнятся примерно также как в варианте mazzy.

Последний раз редактировалось fed; 06.06.2011 в 12:12.
За это сообщение автора поблагодарили: lev (2).
Старый 06.06.2011, 12:07   #7  
Katuxa is offline
Katuxa
Участник
 
36 / 10 (1) +
Регистрация: 13.05.2011
Дело в том, что таблица параметров (buildParam) и таблица объектов (buildTable) не связаны между собой. Они связаны через таблицу значений параметров, в ней есть код объекта ЖКХ и код параметра.
Старый 06.06.2011, 12:18   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Katuxa Посмотреть сообщение
Они связаны через таблицу значений параметров, в ней есть код объекта ЖКХ и код параметра.
связаны? именно в прошедшем времени?
вы же сейчас СОЗДАЕТЕ связи. причем создаете ВСЕ-СО-ВСЕМИ.
такой тип связи настолько редко применим... может быть, все-таки ошибка в логике?
__________________
полезное на axForum, github, vk, coub.
Старый 06.06.2011, 12:25   #9  
Katuxa is offline
Katuxa
Участник
 
36 / 10 (1) +
Регистрация: 13.05.2011
Цитата:
Сообщение от mazzy Посмотреть сообщение
попробую произнести на русском языке то, что вы написали

================
для каждой записи из buildTable
выбрать ВСЕ (!) записи из buildParam // в результате buildParm полностью перебирается столько раз сколько записей в buildTable

если нет записи в paramValue для комбинации buildTable, buildParam
то добавить в paramValue
================

во-первых, вы точно хотели выбирать ВСЕ возможные комбинации из buildTable, buildParam?
может эта пара у вас как-то связана?

во-вторых, у вас делается куча вложенных маленьких запросов внутри цикла.
по сути дела SQL-сервер захлебывается (ddos'ится).

попробуйте объединить запросы в один.
если логика правильна, то примерно так:
X++:
ttsbegin;
  while select BuildCode from buildTable
  join buildParam
  not exists join ParamCode from paramValue where paramValue.BuildCode == buildTable.BuildCode
                                        && paramValue.ParamCode == buildParam.ParamCode;
  {
     paramValue.BuildCode = buildTable.BuildCode;
     paramValue.ParamCode = buildParam.ParamCode;
     paramValue.insert();
  }
  ttscommit;
обратите внимание, что в этом случае запрос на SQL-сервер посылается один раз.
SQL-сервер один раз обрабатывает этот более сложный запрос вместо кучи маленьких.
далее мы от него получаем результаты один раз, а не внутри цикла.
накладных расходов меньше. profit.

будьте внимательны с not exists join в Аксапте (поищите на форуме, обсуждалось)
Сделала так, уже намного быстрее работает (за одну минуту). Спасибо! Но сейчас попробую еще другие предложенные варианты, может получится дойти до оптимального времени.
Старый 06.06.2011, 12:58   #10  
Katuxa is offline
Katuxa
Участник
 
36 / 10 (1) +
Регистрация: 13.05.2011
УРА!!!! Уже работает быстро . Вместо insert() использовала RecordInsertList.
Всем огромное спасибо за помощь!!!
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Неправильный тип аргумента функции преобразования S.Kuskov DAX: Программирование 3 07.02.2020 10:49
Журнал работы пользователей (логи)? Anais DAX: Администрирование 7 26.08.2009 09:15
Функции встроенного SQL для работы с датой Jab Straight DAX: Программирование 6 09.08.2007 00:56
Использование профилировщика и толкование результатов его работы belugin DAX: Программирование 3 22.11.2005 16:56
Есть ли функции работы со строками? kostas DAX: Программирование 2 13.05.2004 11:50

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

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

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