В плане запроса стоит Index Seek. Это я неудачно выразился
Кстати, спасибо за Perfomance. Посмотрел, какие же планы запроса формируются для курсоров. Получилось то, что я и предполагал с самого начала.
Если используется Inner Join, то сначала идет выборка по wmsBillOfLadingOrder, а затем, найденные значения используются как фильтр при поиске по SalesLine (scalar operator)
А вот в случае с Exists Join происходит обратное. Сначала выполняется поиск по SalesLine, а потом, найденные значения проверяются по wmsBillOfLadingOrder. Естесственно, получаем дикие тормоза.
При этом, если те же самые запросы напрямую выполнять в Managment Studio, то в обоих случаях сначала выполняется запрос по wmsBillOfLadingOrder, а запрос по SalesLine уже использует его результаты.
Чтобы уж совсем быть уверенным, напрямую в Managment Studio написал создание курсоров и их Fetch
Код:
DECLARE SalesLine_cursor CURSOR FOR
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.BILLOFLADINGID='101') AND (B.INVENTTRANSREFID=A.SALESID)))
OPEN ...
FETCH ...
DECLARE SalesLine_cursor CURSOR FOR
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.BILLOFLADINGID='101')
AND (B.INVENTTRANSREFID=A.SALESID))))
OPEN ...
FETCH ...
Результат получился такой же, как и при работе sp_cursoropen, sp_cursorfetch. Т.е. принципиально другой план выполнения запросов чем в случае прямого Select
Так что, очевидно, что просто как-то по разному работает планировщик запросов в курсорах и в прямых запросах. И от Axapta здесь вообще ничего и никак не зависит!
Конечно, возможно это происходит потому, что количество записей в SalesLine по одной компании порядка 500 тысяч, а по wmsBillOfLadingOrder - около 2 тысяч. Просто пока мало статистики по второй таблице...