Показать сообщение отдельно
Старый 16.04.2010, 18:32   #8  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,656 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Wamr Посмотреть сообщение
не надо "кошмарить" системные процедуры - включите профайлинг в режиме TSQL_SPs
Это в смысле "не читал, но осуждаю"?

Ну, вот последний по времени пример, когда опять напоролся на ту же проблему

X++:
   while select ItemId, SalesQty, LineAmount, salesId
        from salesLine
        where   salesLine.SalesQty  != 0
        exists join wmsBillOfLadingOrder
//        join TableId from wmsBillOfLadingOrder
        where   wmsBillOfLadingOrder.inventTransRefId   == salesLine.SalesId
            &&  wmsBillOfLadingOrder.billOfLadingId     == "101"
    {
        info(salesLine.ItemId);
    }
Профайлер показывает время выполнения Duration = 2243. Комментирую exists join и ставлю join TableId. Профайлер показывает Duration = 21

Как говорится, "почувствуйте разницу"! На два порядка! 2243 и 21.

Если же посмотреть где именно тратятся ресурсы, то в случае с inner join небольшое время тратится на команде "exec sp_cursoropen". А вот в случае с exist открытие курсора происходит мгновенно, но бешенная задержка не первой команде "exec sp_cursorfetch" после открытия курсора

Если же выдернуть оба запроса, которые прошли через профайлер, в Managment Studio, то время их исполнения практически одинаковое. План запросов делит их в процентном отношении ровно по 50%

Хотя, согласен, что TSQL_SPs показал, что запрос никак не делится. Как был Exists, так и остался. Но, от этого ничуть не легче...

Очевидно, что внутри "exec sp_cursoropen" его обработка выполняется как-то иначе, чем в Managment Studio. И опять же, от Axapta тут ничего не зависит!

Да, для порядка, профайлер показал, что на сервер ушли такие запросы

Код:
SELECT A.ITEMID,A.SALESQTY,A.LINEAMOUNT,A.SALESID,A.RECID 
FROM SALESLINE A 
WHERE ((A.DATAAREAID='цтр') 
	AND (A.SALESQTY<>0)) 
	AND EXISTS (SELECT 'x' FROM WMSBILLOFLADINGORDER B 
		WHERE ((B.DATAAREAID='цтр') 
			AND ((B.INVENTTRANSREFID=A.SALESID) 
			AND (B.BILLOFLADINGID='101'))))

SELECT A.ITEMID,A.SALESQTY,A.LINEAMOUNT,A.SALESID,A.RECID 
FROM SALESLINE A,WMSBILLOFLADINGORDER B 
WHERE ((A.DATAAREAID='цтр') 
	AND (A.SALESQTY<>0)) 
	AND ((B.DATAAREAID='цтр') 
	AND ((B.INVENTTRANSREFID=A.SALESID) 
	AND (B.BILLOFLADINGID='101')))
План запроса в Managment Studio показывает, что в обоих случаях основное время тратится на сканирование по индексу SalesLineIdx (91%)
За это сообщение автора поблагодарили: gl00mie (3).