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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.04.2006, 13:44   #1  
sese is offline
sese
Участник
 
23 / 10 (1) +
Регистрация: 20.03.2006
господа, не будучи профессиональным программистом по образованию ("только" физ.-мат.), возмоно, задам глупый вопрос. Пожалуйста, не кидайтесь в меня тапками.

Итак,

While select * from Table1
{
Variable1 += Table1.Field1;
}

Некоторые поля Field1 нулевые. Иногда их много, иногда все больше нуля.
Будет ли быстрее работать машина, если я напишу так:

While select * from Table1
where Table1.Field1 > 0
{
Variable1 += Table1.Field1;
}

?

И если будет быстрее, существенно ли или пренебрежимо? А если этот цикл выполнять не раз, а сто раз подряд?


И что быстрее:

while select * from Table1
where <condition1>
{
...
}
while select * from Table1
where <condition2>
{
...
}

или

while select * from Table1
{
switch (<condition>)
{
<condition1>: ...; break;
<condition2>: ...; break;
}
}

?
Старый 24.04.2006, 13:56   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от sese Посмотреть сообщение
While select * from Table1
where Table1.Field1 > 0
{
Variable1 += Table1.Field1;
}
Да, будет работать быстрее.
Даже за счет того, что по сети передается меньше данных.

За счет чего запрос с where будет быстрее:
1. За счет того, что SQL-сервер прочитает меньше данных с диска (он бывает достаточно сообразителен)
2. За счет того, что SQL-сервер передаст меньший объем данных Аксапте (обычно передача идет по сравнительно медленной сети)
3. За счет того, что Аксапта выполнит меньшее число скомпилированный в p-код инструкций (p-код выполняетсяпо медленно по сравнению с ассемблерными инструкциям SQL-сервера)

В самом худшем случае время выполнения запроса с where будет таким же.
Это для простых запросов.


Надо помнить и об обратной стороне.
Очень сложные запросы могут выполняться медленнее, нежели несколько простых. Даже в том, случае, если сложный запрос возвращает меньше данных.
Дело в том, что запрос на SQL-сервер передается как текстовая строка.
И SQL-сервер каждый раз выполняет компиляцию и оптимизацию запроса.
Время компиляции сложного запроса может быть очень велико (да, там есть свои механизмы для уменьшения времени компиляции).

Подробнее читайте BOL (book online) и материалы по SQL-сервер.
__________________
полезное на axForum, github, vk, coub.
Старый 24.04.2006, 14:01   #3  
sese is offline
sese
Участник
 
23 / 10 (1) +
Регистрация: 20.03.2006
mazzy, спасибо!!! Если вас не затруднит, посмотрите еще на сделанное мной добавление к вопросу.
Старый 24.04.2006, 14:05   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от sese Посмотреть сообщение
И что быстрее:

while select * from Table1
where <condition1>
{
...
}
while select * from Table1
where <condition2>
{
...
}

или

while select * from Table1
{
switch (<condition>)
{
<condition1>: ...; break;
<condition2>: ...; break;
}
}
В общем случае при достаточно простых условиях (а только такие можно поместить в case оператора switch ) быстрее будет так
<div class='XPPtop'>X++</div><div class='XPP'>
[color=:blue]while[/color] [color=:blue]select[/color] * [color=:blue]from[/color] Table1
[color=:blue]where[/color] <condition1> [color=:blue]||[/color] <condition2>
{
[color=:blue]switch[/color] (<condition>)
{
<condition1>: ...; [color=:blue]break[/color];
<condition2>: ...; [color=:blue]break[/color];
}
}</div>

Так вы и выборку данных уменьшаете.
И обходитесь одним запросом.

Однако, обратите внимание, что при сложных условиях, скорее всего, лучше будет сделать несколько простых запросов с несколькими циклами. Чтобы получить точный ответ надо смотреть в профайлер.
__________________
полезное на axForum, github, vk, coub.
Старый 24.04.2006, 14:09   #5  
sese is offline
sese
Участник
 
23 / 10 (1) +
Регистрация: 20.03.2006
mazzy,
Старый 24.04.2006, 20:06   #6  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы


Код:
select sum(Field1) from Table1 where Table1.Field1 > 0;
Variable1 = Table1.Field1;
вместо

Код:
While select * from Table1
where Table1.Field1 > 0
{
Variable1 += Table1.Field1;
}
Постоянно слышу разговоры о том, что запрос, разбитый на несколько мелких, работает (может работать) быстрее. Примеров, подтверждающих это, почему-то никто не приводит
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.04.2006, 00:08   #7  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Vadik Посмотреть сообщение
вместо
Точно!
Если это допустимо. Подозреваю, что тело цикла было вставлено сугубо для примера.

Цитата:
Сообщение от Vadik Посмотреть сообщение
Постоянно слышу разговоры о том, что запрос, разбитый на несколько мелких, работает (может работать) быстрее. Примеров, подтверждающих это, почему-то никто не приводит
IMTS
Включена ли у вас в Аксапте система множественных складских транзакций?


Согласен, там длинная цепочка для получения вывода.
Надо начать с того, что длинная транзакция разбивается на множество мелких...
Твои ответы в опросе - перечитал еще раз.
__________________
полезное на axForum, github, vk, coub.
Старый 25.04.2006, 09:44   #8  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
where Table1.Field1 > 0
А Вы уверены, что у Вас все данные больше 0? И не надо суммировать данные меньше 0? И подобные данные не появятся в будущем?

Поаккуратнее с оптимизацией Сколько багов случалось именно из-за желания "пооптимизировать"


Удачи!

С Уважением,
Георгий
Старый 25.04.2006, 10:53   #9  
Владимир Максимов_imported is offline
Владимир Максимов_imported
Участник
 
33 / 10 (1) +
Регистрация: 20.01.2004
Цитата:
Сообщение от Vadik Посмотреть сообщение
Постоянно слышу разговоры о том, что запрос, разбитый на несколько мелких, работает (может работать) быстрее. Примеров, подтверждающих это, почему-то никто не приводит
Вот ЭТО будет работать относительно долго
Код:
while select LineNum, ItemId, Dimension
	from salesLine
	where salesLine.SalesId == ...
		join Description
		from dimensions
		where dimensions.Num == salesLine.Dimension[1]
			&& dimensions.DimensionCode == SysDimension::Department
{
...
}
А вот такое разделение ускорит выполнение кода примерно на 10%

Код:
while select LineNum, ItemId, Dimension
	from salesLine
	where salesLine.SalesId == ...
{
	select firstonly Description
	from dimensions
	where dimensions.Num == salesLine.Dimension[1]
		&& dimensions.DimensionCode == SysDimension::Department
...
}
Здесь сошлось несколько причин. Хотя, в общем случае, объединение по join работает быстрее чем вложенные циклы, но при подключении таблицы финансовых аналитик ВСЕГДА имеем тормоза по сравнению с прямым запросом внутри while select
Старый 25.04.2006, 11:18   #10  
mugz is offline
mugz
Участник
 
107 / 10 (1) +
Регистрация: 05.08.2004
У меня были случае когда несколько мелких запросов работало быстрее:

1. Baan + BaanBase
BaanBase довольно тупая база данных, поставлявшаяся с Baan IV. На ней что-то сложное работало всегда медленней чем что-то несложное, при этом была большая скорость обмена данных с бааном

2. Baan + Oracle - в таблице было большое количество индексов, и оракл почему-то использовал неправильный. Разбиение на два запроса помогло ораклу разобраться что к чему

Еще есть соображение по поводу кеширования: если есть маленький справочник и большая таблица с данными, то выборка по отдельности теоретически может быть быстрее джоина т.к. справочник может закешироваться и объекм пересылаемых между звеньями данных может уменьшиться.

...
>>>А Вы уверены, что у Вас все данные больше 0? И не надо суммировать данные меньше 0? И подобные данные не появятся в будущем?

рекомендую при длительной оптимизации (то есть когда долго что-то оптимизируется да и вообще при длительных эквивалентных преобрзованиях), заиксировать набор исходных данных и запускать unit test на нем - тогда при ошибке сразу получаешь по мозгам.
 


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

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

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