24.04.2006, 13:44 | #1 |
Участник
|
господа, не будучи профессиональным программистом по образованию ("только" физ.-мат.), возмоно, задам глупый вопрос. Пожалуйста, не кидайтесь в меня тапками.
Итак, 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 |
Участник
|
Цитата:
Даже за счет того, что по сети передается меньше данных. За счет чего запрос с where будет быстрее: 1. За счет того, что SQL-сервер прочитает меньше данных с диска (он бывает достаточно сообразителен) 2. За счет того, что SQL-сервер передаст меньший объем данных Аксапте (обычно передача идет по сравнительно медленной сети) 3. За счет того, что Аксапта выполнит меньшее число скомпилированный в p-код инструкций (p-код выполняетсяпо медленно по сравнению с ассемблерными инструкциям SQL-сервера) В самом худшем случае время выполнения запроса с where будет таким же. Это для простых запросов. Надо помнить и об обратной стороне. Очень сложные запросы могут выполняться медленнее, нежели несколько простых. Даже в том, случае, если сложный запрос возвращает меньше данных. Дело в том, что запрос на SQL-сервер передается как текстовая строка. И SQL-сервер каждый раз выполняет компиляцию и оптимизацию запроса. Время компиляции сложного запроса может быть очень велико (да, там есть свои механизмы для уменьшения времени компиляции). Подробнее читайте BOL (book online) и материалы по SQL-сервер. |
|
24.04.2006, 14:01 | #3 |
Участник
|
mazzy, спасибо!!! Если вас не затруднит, посмотрите еще на сделанное мной добавление к вопросу.
|
|
24.04.2006, 14:05 | #4 |
Участник
|
Цитата:
<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> Так вы и выборку данных уменьшаете. И обходитесь одним запросом. Однако, обратите внимание, что при сложных условиях, скорее всего, лучше будет сделать несколько простых запросов с несколькими циклами. Чтобы получить точный ответ надо смотреть в профайлер. |
|
24.04.2006, 14:09 | #5 |
Участник
|
mazzy,
|
|
24.04.2006, 20:06 | #6 |
Модератор
|
Код: 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 |
Участник
|
Точно!
Если это допустимо. Подозреваю, что тело цикла было вставлено сугубо для примера. Цитата:
Включена ли у вас в Аксапте система множественных складских транзакций? Согласен, там длинная цепочка для получения вывода. Надо начать с того, что длинная транзакция разбивается на множество мелких... Твои ответы в опросе - перечитал еще раз. |
|
25.04.2006, 09:44 | #8 |
Модератор
|
Цитата:
where Table1.Field1 > 0
Поаккуратнее с оптимизацией Сколько багов случалось именно из-за желания "пооптимизировать" Удачи! С Уважением, Георгий |
|
25.04.2006, 10:53 | #9 |
Участник
|
Цитата:
Код: while select LineNum, ItemId, Dimension from salesLine where salesLine.SalesId == ... join Description from dimensions where dimensions.Num == salesLine.Dimension[1] && dimensions.DimensionCode == SysDimension::Department { ... } Код: 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 ... } |
|
25.04.2006, 11:18 | #10 |
Участник
|
У меня были случае когда несколько мелких запросов работало быстрее:
1. Baan + BaanBase BaanBase довольно тупая база данных, поставлявшаяся с Baan IV. На ней что-то сложное работало всегда медленней чем что-то несложное, при этом была большая скорость обмена данных с бааном 2. Baan + Oracle - в таблице было большое количество индексов, и оракл почему-то использовал неправильный. Разбиение на два запроса помогло ораклу разобраться что к чему Еще есть соображение по поводу кеширования: если есть маленький справочник и большая таблица с данными, то выборка по отдельности теоретически может быть быстрее джоина т.к. справочник может закешироваться и объекм пересылаемых между звеньями данных может уменьшиться. ... >>>А Вы уверены, что у Вас все данные больше 0? И не надо суммировать данные меньше 0? И подобные данные не появятся в будущем? рекомендую при длительной оптимизации (то есть когда долго что-то оптимизируется да и вообще при длительных эквивалентных преобрзованиях), заиксировать набор исходных данных и запускать unit test на нем - тогда при ошибке сразу получаешь по мозгам. |
|