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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 22.01.2009, 18:49   #1  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
2 while select или join?
Я всегда считал, что join таблиц отрабатывает быстрее чем 2 while select`а. Но вот увидел в коде двойной while select и решил "исправить". После переписывания запроса на join код стал выполняться дольше. Написал простой job
X++:
static void JobJoin(Args _args)
{
    SalesTable      SalesTable;
    SalesLine       SalesLine;
    int             startTime, endTime, i;
    ;

    startTime = timenow();
    while select SalesTable
    {
        while select SalesLine
           where SalesLine.SalesId == SalesTable.SalesId
        {
            i++;
        }
    }
    endTime = timenow();
    info(strFmt("2 while select: %1, i = %2", endTime - startTime, i));

    i = 0;
    startTime = timenow();
    while select SalesTable
        join SalesLine
            where SalesLine.SalesId == SalesTable.SalesId
    {
            i++;
    }

    endTime = timenow();
    info(strFmt("join: %1, i = %2", endTime - startTime, i));
}
У меня получилось (Ax 3.0 SP3 KR2, SQL2005 SP2)
X++:
2 while select: 99, i = 56347
join: 129, i = 56347
Получается что 2 while select'а отрабатывают быстрее Может кто нибудь дать научное обоснование сему явлению?
Старый 22.01.2009, 19:09   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
1. Для джоина мог быть выбран неудачный план запроса, так что формироание выборки могло занять слишком много времени.
2. Объем прокачанных данных во втором случае выше, так как для каждой salesLine передавалась еще и salesTable - больше клиент серверных вызовов было.

но скорее всего п.1
За это сообщение автора поблагодарили: _scorp_ (1).
Старый 22.01.2009, 20:07   #3  
petr is offline
petr
Участник
Соотечественники
 
561 / 201 (8) ++++++
Регистрация: 30.05.2005
Адрес: Швейцария
Какой способ будет быстрее и насколько зависит от отношения количества записей в salesTable и salesLine.

При одной записе в salesTable и 100 в salesLine - быстрее будет while select - см. пред. пост.

При одинаковом кол-ве записей в salesTable и salesLine - быстее будет join.
За это сообщение автора поблагодарили: _scorp_ (1).
Старый 23.01.2009, 11:27   #4  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Объем прокачанных данных во втором случае выше, так как для каждой salesLine передавалась еще и salesTable - больше клиент серверных вызовов было.
Получается, что на тонком клиенте лучше использовать 2 while select.
Старый 23.01.2009, 11:42   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Провёл небольшие "исследования", вот некоторые выкладки. Мысли в конце.

Цитата:
Oracle, Master\Detail:
2 while select: 400, i = 128285
join: 255, i = 128285
Причём, если аналог прокрутить на БД с использованием PL\SQL, то результаты - 18 и 14 сек! Чувствуется разница. Это на тему влияния RPC и перекачки данных по сети...
Но пропорции времени в пользу join.
На бОльших объёмах - разница ещё больше.


Oracle, 2theSameTables:
2 while select: 195, i = 10213
join: 23, i = 10213
Пропорции (сторона) сохраняются (и даже увеличиваются) при одинаковом кол-ве записей

MSSQL2005, Master\Detail:
2 while select: 45, i = 68825
join: 148, i = 68825
На сиквеле действительно картина обратная

MSSQL2005, 2theSameTables:
while select: 222, i = 68825
join: 57, i = 68825
Пропорции меняются на обратные
Почему так происходит? когда идёт соединение маленькой + большой таблиц сиквел предпочитает использовать в Nested Loop доступ к первой таблице по кластерному индексу. Во втором случае, когда 2 большие одинаковые таблицы - full scan. Ко второй таблице по индексу в обоих случаях. Похоже за счёт этого такая картина... Хотя я всё равно не понимаю почему такая большая разница... Это скорее вопрос к гуру сиквела, почему cluster index scan так тормозит....

Oracle же в обоих случаях использует hash join.
но, даже если уговорить его использовать нестедлуп, то картина не менятся особо - всё равно джоин быстрее...
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: _scorp_ (2).
Старый 23.01.2009, 11:48   #6  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от _scorp_ Посмотреть сообщение
Получается, что на тонком клиенте лучше использовать 2 while select.
В общем случае - крайне спорное утверждение.
Хотя в некоторых конкретных случаях может быть правдой... всё зависит от ситуации и плана джоина... (см. предыдущий пост)
__________________
Zhirenkov Vitaly
Старый 23.01.2009, 12:29   #7  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
имхо 2 while select'a надежней)))
просто если в обоих таблицах скажем по 10 000 000 записей (inventTrans и т.п.) то join может не отработать никогда и при это сложить бд)
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy
Старый 23.01.2009, 14:43   #8  
petr is offline
petr
Участник
Соотечественники
 
561 / 201 (8) ++++++
Регистрация: 30.05.2005
Адрес: Швейцария
Цитата:
Сообщение от ivas Посмотреть сообщение
имхо 2 while select'a надежней)))
просто если в обоих таблицах скажем по 10 000 000 записей (inventTrans и т.п.) то join может не отработать никогда и при это сложить бд)
Не забывайте про контекст задачи, исходно вопрос стоял про salesTable - salesLine, там не должно быть более 10 000-100 000 записей.

ИМХО, большая проблема этих таблиц - большое кол-во полей (плюс еще каждое гориз./верт. решение добавляет десяток другой. Так что прирост производительности должно дать задание необходимых полей для выборки (если это возможно)ю
Старый 23.01.2009, 15:33   #9  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от petr Посмотреть сообщение
Не забывайте про контекст задачи, исходно вопрос стоял про salesTable - salesLine, там не должно быть более 10 000-100 000 записей.
Ну это как сказать.
я знаю примеры когда в salesTable больше 700 тыс. записей (причем в одной компании)
SalesLine - десятки миллионов.
Старый 23.01.2009, 16:02   #10  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Цитата:
Не забывайте про контекст задачи, исходно вопрос стоял про salesTable - salesLine, там не должно быть более 10 000-100 000 записей.
хм... у нас
SalesTable 344114
SalesLine 383276

парулет назад в SalesLine было больше 2 000 000 записей вот вам и контекст...
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Разница NotInTTS и Found Logger DAX: База знаний и проекты 6 18.09.2008 12:35
Что лучше select RecId или select TableId Logger DAX: Программирование 9 02.06.2007 15:13
Глюки в Query с разными типами Join (в т.ч. NonExistsJoin) к одной таблице gl00mie DAX: Программирование 10 14.02.2007 13:22
Вопрос про Demand Planner slava09 DAX: Функционал 4 25.09.2006 11:43
Join трех таблиц (две к одной) ATimTim DAX: Программирование 25 03.02.2005 11:31

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

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

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