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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 22.06.2007, 07:41   #1  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Почему join запрос разбивается на подзапросы!?
Axapta 3.0 SP 3

Имеем запрос:

Код:
    while select _rassetTable
        index RAssetNumIdx
        where _rassetTable.VGP_PropertyTax          == NoYes::Yes
    join firstonly _rassetTrans
        index TransTypeIdx
        where _rassetTrans.AccountNum               == _rassetTable.AccountNum          &&
              _rassetTrans.AssetTransType           == RAssetTransType::Acquisition     &&
              _rassetTrans.TransDate                <= reportDateEnd
    join firstonly _ledgerTrans
        index VGP_LedgerLinkIdx
        where _ledgerTrans.VGP_LedgerLinkId         == _rassetTrans.VGP_LedgerLinkId    &&
              _ledgerTrans.VGP_LedgerLinkModuleRef  == VGP_LedgerLinkModuleRef::RAsset  &&
              _ledgerTrans.Voucher                  == _rassetTrans.Voucher             &&
              _ledgerTrans.TransDate                == _rassetTrans.TransDate
{
	…….
	//Не значительный код, заполняется мап
}
При просмотре системным монитором видим:
Кол-во Select 4837 !!!!!?!?!? Почему?! Запрос отрабатывает порядка 25 минут

Написал такой же запрос в SQL Enterprise Manager отработал за 5 секунд!!
Прямой запрос, вставлять в код не очень хочется … .. . Подскажите в чём дело и что можно сделать?!
Старый 22.06.2007, 09:25   #2  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Хм. А пробовали убрать firstonly?
Вполне возможно, что для каждой записи rAssetTable делается поиск записи соответствия свой вместо простого объединения таблиц.
(как будто бы join вообще не было, а в теле while Вы отдельно искали требуемые записи)

Хотя, это всего лишь предположение - возможно кто-то поправит.
За это сообщение автора поблагодарили: 3oppo (1).
Старый 22.06.2007, 09:29   #3  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Интересно, а какой, по вашему, запрос должен сформироваться?
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: 3oppo (1).
Старый 22.06.2007, 09:40   #4  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Уровень кэширования на таблице RAssetTable у вас стандартный? Это не экземпляр временной таблицы? Запросы всегда разбиваются, если в них включена таблица с уровнем кэширования EntireTable или временная таблица.
__________________
С уважением,
glibs®
За это сообщение автора поблагодарили: zemlyn (1), kashperuk (5), Мариночка (2), 3oppo (1).
Старый 22.06.2007, 11:02   #5  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Да пробовал убирать firstonly без результатно!

X++:
    while select RPayJournalTable
        where RPayJournalTable.JournalId == 'ЗП000628'
    join RPayJournalTrans
        where RPayJournalTrans.JournalId ==  RPayJournalTable.JournalId
    join RPayTrans
        where RPayTrans.SourceRecId     == RPayJournalTrans.RecId
    {
         i++;
    }
    box::info( int2str(i) );
Вот этот код выполняется за 2 select-a

to AndyD ну уж никак не из 4000 селектов!
RAssetTable стандартно не каких временных таблиц!
Старый 22.06.2007, 18:04   #6  
MPAKObec is offline
MPAKObec
Участник
 
4 / 11 (1) +
Регистрация: 06.06.2007
Насколько я понял firstonly в join-ах вообще игнорируются. У меня тоже как то получалось что join разбивал select но я так и не разобрался в чём там дело. Просто используй «прямой запрос» к базе, сам так делал. Выигрыш в скорости в РАЗЫ!!
За это сообщение автора поблагодарили: 3oppo (1).
Старый 22.06.2007, 18:09   #7  
MPAKObec is offline
MPAKObec
Участник
 
4 / 11 (1) +
Регистрация: 06.06.2007
А вы. Не пробовали использовать стандартные Query?! Он вроде как быстрее должен работать!
Старый 22.06.2007, 18:36   #8  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Попробовал написать джоб похожий (на стандартной функциональности только). Select один при декларировании курсора. Дольше идут вызовы управления курсором.

Либо вы чего-то не договариваете...

А какой вид у вас имеют все 4837 запроса? Они абсолютно одинаковы? Может у вас сам метод столько раз вызывается? Тогда не удивлюсь насчет 25 мин.
__________________
С уважением,
glibs®
Старый 22.06.2007, 21:58   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от MPAKObec Посмотреть сообщение
Просто используй «прямой запрос» к базе, сам так делал. Выигрыш в скорости в РАЗЫ!!
Прямой запрос означает полный отказ от поддерки ядра
Прямой запрос в разы сложнее отлаживать и в разы дороже в сопровождении.
Прежде чем следовать совету МРАКОбеса триджы подумайте.
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: 3oppo (1).
Старый 25.06.2007, 08:32   #10  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Цитата:
Сообщение от glibs Посмотреть сообщение
Попробовал написать джоб похожий (на стандартной функциональности только). Select один при декларировании курсора. Дольше идут вызовы управления курсором.

Либо вы чего-то не договариваете...
.

Вот метод полностью:

X++:
protected Map initRasset01Map()
{
    Map             _ret          = new Map(Types::String, Types::Date);
    Set             _account01Set = this.initAccount01Set();
    RAssetTable     _rassetTable;
    RAssetTrans     _rassetTrans;
    LedgerTrans     _ledgerTrans;
    int             i, ip4, ip2, ip3;

    while select _rassetTable
       index RAssetNumIdx
        where _rassetTable.VGP_PropertyTax          == NoYes::Yes
    join firstonly _rassetTrans
        index TransTypeIdx
        where _rassetTrans.AccountNum               == _rassetTable.AccountNum          &&
              _rassetTrans.AssetTransType           == RAssetTransType::Acquisition     &&   
              _rassetTrans.TransDate                <= reportDateEnd
    join firstonly _ledgerTrans
        index VGP_LedgerLinkIdx
        where _ledgerTrans.VGP_LedgerLinkId         == _rassetTrans.VGP_LedgerLinkId    &&
              _ledgerTrans.VGP_LedgerLinkModuleRef  == VGP_LedgerLinkModuleRef::RAsset  &&   //ОС
              _ledgerTrans.Voucher                  == _rassetTrans.Voucher             &&
              _ledgerTrans.TransDate                == _rassetTrans.TransDate

    {
        i++;
        if (_account01Set.in(_ledgerTrans.AccountNum))
        {
            _ret.insert(_rassetTable.AccountNum, this.getDisposalDate(_rassetTable.AccountNum));
        }
    }

//    box::info( int2str(i) );

    return _ret;
}
Ставлю точку останова в начале метода и в конце, и между 2ми этими точками включаю монитор.
Переписал на прямой запрос в той же функции, выполняется вместо 26 минут - 30 секунд.


Цитата:
Сообщение от glibs Посмотреть сообщение
А какой вид у вас имеют все 4837 запроса? Они абсолютно одинаковы?

Посмотрел генерируемые запросы, вроде одинаковые вот такого вида:

SELECT A.TRANSDATE,A.RECID,A.VGP_LEDGERLINKID FROM RASSETTRANS A(INDEX(I_16077RASSETDATEIDX)) WHERE ((DATAAREAID=?) AND (((ACCOUNTNUM=?) AND (TRANSDATE<?)) AND ((((ASSETTRANSTYPE=?) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)))) OPTION(FAST 2)

внутри проскакивают 2-3 другого вида но непонятно к чему они относятся.

Цитата:
Сообщение от glibs Посмотреть сообщение
Может у вас сам метод столько раз вызывается? Тогда не удивлюсь насчет 25 мин.
Старый 25.06.2007, 08:38   #11  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Цитата:
Сообщение от mazzy Посмотреть сообщение
Прямой запрос означает полный отказ от поддерки ядра
Не совсем понял о чём речь?

Цитата:
Сообщение от mazzy Посмотреть сообщение
Прямой запрос в разы сложнее отлаживать и в разы дороже в сопровождении.
Прежде чем следовать совету МРАКОбеса триджы подумайте.
Согласен! А что делать?! Если разница в скорости в 50 раз!!!
Старый 25.06.2007, 09:06   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от 3oppo Посмотреть сообщение
Не совсем понял о чём речь?
Нисколько не сомневаюсь, что не поняли.
Но тем не менее категорично советуете.

для начала назову пару вещей: виртуальные компани, rls.
про autorelation, временные таблицы, вычисляемые поля, про енумы, про целостность, про переопределенные методы при чтении/вставке/записи/удалении и т.п. уж как-нибудь сами.
в общем, rtfm.


Цитата:
Сообщение от 3oppo Посмотреть сообщение
Согласен! А что делать?! Если разница в скорости в 50 раз!!!
Во-первых, грамотно использовать втроенные средства.
Во-вторых, прекратите мерить разницу в монопольном режиме. Хоть раз померяйте при нормальной загрузке sql-сервера с нормальным числом пользователей. Замерьте наконец задержки, которые происходят у других пользователей из-за ваших прямых запросов. Барабашки нет.
__________________
полезное на axForum, github, vk, coub.
Старый 25.06.2007, 09:25   #13  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от 3oppo Посмотреть сообщение
Вот метод полностью:
...
Посмотрел генерируемые запросы, вроде одинаковые вот такого вида:

SELECT A.TRANSDATE,A.RECID,A.VGP_LEDGERLINKID FROM RASSETTRANS A(INDEX(I_16077RASSETDATEIDX)) WHERE ((DATAAREAID=?) AND (((ACCOUNTNUM=?) AND (TRANSDATE<?)) AND ((((ASSETTRANSTYPE=?) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)) OR (ASSETTRANSTYPE=?)))) OPTION(FAST 2)

внутри проскакивают 2-3 другого вида но непонятно к чему они относятся.
По-моему, этот запрос не имеет отношнения к приведенному в коде (возможно, формируется в методе getDisposalDate()?).
Здесь идет связка по OR для нескольких условий для ASSETTRANSTYPE, а в коде x++ - по одному.

Попробуйте оставить только выборку и цикл по ней и посмотрите на результат запроса.
__________________
Axapta v.3.0 sp5 kr2
Старый 25.06.2007, 09:34   #14  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
Сообщение от mazzy Посмотреть сообщение
для начала назову пару вещей: виртуальные компани, rls.
про autorelation, временные таблицы, вычисляемые поля, про енумы, про целостность, про переопределенные методы при чтении/вставке/записи/удалении и т.п.
Забыл про самое страшное - про блокировки.

Как только вижу в коде прямое обращние к базе, это с 99% вероятностью означает, что барабашка скоро появится.

С Уважением,
Георгий
За это сообщение автора поблагодарили: 3oppo (1).
Старый 25.06.2007, 09:45   #15  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Цитата:
Сообщение от mazzy Посмотреть сообщение
Нисколько не сомневаюсь, что не поняли.
?????

Цитата:
Сообщение от mazzy Посмотреть сообщение
для начала назову пару вещей: виртуальные компани, rls.
про autorelation, временные таблицы, вычисляемые поля, про енумы, про целостность, про переопределенные методы при чтении/вставке/записи/удалении и т.п. уж как-нибудь сами.
в общем, rtfm.
А вы в этом смысле. Ну да есть некоторые неудобства. Но почти всё обходится дополнительным программированием.


Цитата:
Сообщение от mazzy Посмотреть сообщение
Во-первых, грамотно использовать втроенные средства.
Научите плиз!? Вдруг чего не знаю.

Цитата:
Сообщение от mazzy Посмотреть сообщение
Во-вторых, прекратите мерить разницу в монопольном режиме. Хоть раз померяйте при нормальной загрузке sql-сервера с нормальным числом пользователей.
Все замеры только на рабочей базе!

Цитата:
Сообщение от mazzy Посмотреть сообщение
Замерьте наконец задержки, которые происходят у других пользователей из-за ваших прямых запросов.
Если это даже все 30 сек. (думаю что ЗНАЧИТЕЛЬНО меньше) это не критично для отчёта запускаемого 2 раза в месяц.

Цитата:
Сообщение от mazzy Посмотреть сообщение
Барабашки нет.
Судя по оставшемуся главному вопросу, он всё таки есть!
Старый 25.06.2007, 09:53   #16  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Пробовал коментарить код внутри цикла, на времени выполнения это не отразилось.
Старый 25.06.2007, 10:06   #17  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Еще можно включить трассировку SQL и походить по шагам внимательно глядя в список infolog дебаггера. И посмотреть какая строка генерирует приведенный SQL.

Еще можно трассировать SQL в файл и посмотреть по стеку какая строчка его генерит.
За это сообщение автора поблагодарили: 3oppo (1).
Старый 25.06.2007, 10:14   #18  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
не проверял с клиентом SP3, но все же
- какой глубокий смысл заложен в
X++:
join firstonly RAssetTrans
и
X++:
join firstonly LedgerTrans
? Как, по-Вашему, их должен реализовать сервер БД?
- с какой целью используются
X++:
index RAssetNumIdx
index TransTypeIdx
index VGP_LedgerLinkIdx
__________________
-ТСЯ или -ТЬСЯ ?
Старый 25.06.2007, 11:26   #19  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Цитата:
Сообщение от Vadik Посмотреть сообщение
Как, по-Вашему, их должен реализовать сервер БД?
Цитата:
Сообщение от 3oppo Посмотреть сообщение
Да пробовал убирать firstonly без результатно!
Код достался от внедренцев ... .. . Вот пытаюсь разобраться.

Цитата:
Сообщение от AndyD Посмотреть сообщение
По-моему, этот запрос не имеет отношнения к приведенному в коде (возможно, формируется в методе getDisposalDate()?).
Вы оказались правы!
Вот реальный запрос

PHP код:
SELECT 
A
.ACCOUNTNUM… Очень большой список полей из всех 3х таблицВырезал его …
POSTINGJOURNALID
,C.TAXREFID,C.DEL_OFFSETACCOUNTNUM_RU 
FROM RASSETTABLE A
,RASSETTRANS B,LEDGERTRANS C 
WHERE 
((A.DATAAREAID='vgp') AND (A.VGP_PROPERTYTAX=1)) AND
 ((
B.DATAAREAID='vgp') AND (((B.ACCOUNTNUM=A.ACCOUNTNUM) AND (B.ASSETTRANSTYPE=3)) 
AND (
B.TRANSDATE<={ts '2007-03-31 00:00:00.000'}))) 
AND ((
C.DATAAREAID='vgp') AND ((((C.VGP_LEDGERLINKID=B.VGP_LEDGERLINKID
AND (
C.VGP_LEDGERLINKMODULEREF=4)) AND (C.VOUCHER=B.VOUCHER)) 
AND (
C.TRANSDATE=B.TRANSDATE))) 
ORDER BY A.DATAAREAID,A.ACCOUNTNUM,B.DATAAREAID,B.ACCOUNTNUM,
B.ASSETTRANSTYPE,C.DATAAREAID,C.VGP_LEDGERLINKID,
C.VGP_LEDGERLINKMODULEREF OPTION(FAST 4

Последний раз редактировалось 3oppo; 25.06.2007 в 11:29.
Старый 25.06.2007, 12:21   #20  
3oppo is offline
3oppo
Участник
Аватар для 3oppo
 
222 / 32 (2) +++
Регистрация: 30.06.2005
Остался вопрос ПОЧЕМУ ТАК ДОЛГО?! И почему такая большая разница с прямым запросом.
Теги
производительность, запрос (query), ax3.0

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Не отрабатывает запрос EXISTS JOIN Paul_ST DAX: База знаний и проекты 8 21.03.2008 17:21
запрос с 4 таблицами. Загадка с Join Андрей К. DAX: Программирование 7 19.09.2007 17:12
Почему на форме "Пользовательские настройки", когда я перехожу в нее из формы, отсутствует закладка "Запрос"? Hans DAX: Администрирование 0 05.07.2007 13:52
2 join-а + CasheLookup = EntireTable vallys DAX: Программирование 1 10.03.2006 13:20
можно ли сделать с помощью join следующий запрос: SergAY DAX: Программирование 1 29.07.2003 11:39
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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