06.06.2011, 11:23 | #1 |
Участник
|
Оптимизация работы функции
Всем добрый день!
Помогите пожалуйста решить одну проблему. Есть таблица параметров объектов ЖКХ и есть таблица значений параметров для объектов ЖКХ. Нужно в параметрах по нажатию на кнопку занести все параметры, (которые есть в таблице параметров) в таблицу значений параметров для каждого объекта ЖКХ. Написала следующую функцию: 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; } |
|
06.06.2011, 11:32 | #2 |
Участник
|
а чем не устраивает время 2-3 минуты? это такая частая опепация внутри другой, что вам так необходима оптимизация?
для оптимизации добавьте во второй цикл notexists join paramValue Последний раз редактировалось ice; 06.06.2011 в 11:37. |
|
06.06.2011, 11:35 | #3 |
Участник
|
Ну во первых скажите спасибо тому, кто у вас придумал такую структуру данных
Я вижу два решения: 1. Организовать "правильную" структуру, сделать в нее импорт данных и пользоваться. 2. Оставить все как есть, но переписать с использованием RecordInsertList. Не факт что все залетает, но должно быть быстрее. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
06.06.2011, 11:38 | #4 |
Участник
|
попробую произнести на русском языке то, что вы написали
================ для каждой записи из 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-сервер один раз обрабатывает этот более сложный запрос вместо кучи маленьких. далее мы от него получаем результаты один раз, а не внутри цикла. накладных расходов меньше. profit. будьте внимательны с not exists join в Аксапте (поищите на форуме, обсуждалось) |
|
06.06.2011, 11:41 | #5 |
Участник
|
да. и это тоже.
|
|
06.06.2011, 11:59 | #6 |
Moderator
|
Ну и в качестве окончательной оптимизации, если вы используете 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; Да - если у вас переопределен insert() на paramValue, то особого убыстрения не случится, поскольку в этом случае, все будет выполнятся примерно также как в варианте mazzy. Последний раз редактировалось fed; 06.06.2011 в 12:12. |
|
|
За это сообщение автора поблагодарили: lev (2). |
06.06.2011, 12:07 | #7 |
Участник
|
Дело в том, что таблица параметров (buildParam) и таблица объектов (buildTable) не связаны между собой. Они связаны через таблицу значений параметров, в ней есть код объекта ЖКХ и код параметра.
|
|
06.06.2011, 12:18 | #8 |
Участник
|
Цитата:
вы же сейчас СОЗДАЕТЕ связи. причем создаете ВСЕ-СО-ВСЕМИ. такой тип связи настолько редко применим... может быть, все-таки ошибка в логике? |
|
06.06.2011, 12:25 | #9 |
Участник
|
Цитата:
Сообщение от 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-сервер один раз обрабатывает этот более сложный запрос вместо кучи маленьких. далее мы от него получаем результаты один раз, а не внутри цикла. накладных расходов меньше. profit. будьте внимательны с not exists join в Аксапте (поищите на форуме, обсуждалось) |
|
06.06.2011, 12:58 | #10 |
Участник
|
УРА!!!! Уже работает быстро . Вместо insert() использовала RecordInsertList.
Всем огромное спасибо за помощь!!! |
|