Выполнение сохранило proc от DotNet, берет очень долго, но в SSMS это непосредственно

У меня есть сохраненный proc на SQL Server 2000, который берет 3 параметра. Когда я называю сохраненный proc от использования DotNet SqlCommand. ExecuteReader () требуется приблизительно 28 секунд.

Когда я выполняю тот же запрос в SSMS непосредственно, он сразу возвращается.

Когда я вынимаю запрос из сохраненного proc и выполняю его непосредственно использование DotNet, он также сразу возвращается.

Это результаты сессии SQL Profiler

SP в отмечает точкой сеть

  • Продолжительность: 28030
  • Чтения: 2663365
  • Записи: 0

SP в SSMS

  • Продолжительность: 450
  • Чтения: 23535
  • Записи: 65

Запросите непосредственно внутреннюю Точечную Сеть

  • Продолжительность: 360
  • Чтения: 24865
  • Записи: 57

Следующие вещи выделяются мне:

  • Статистика для SSMS и прямого запроса в Точечной Сети очень похожа
  • Точечная Сеть SP каждый делает огромный объем чтений, но никаких записей
  • Другие два делают очень немного чтений, но несколько записей

Любая справка ценилась бы.

Вот немного obviscated версия SP:

Я сомневаюсь, что это - проблема плана запросов, потому что, даже если я неоднократно выполняю его из DotNet, я всегда получаю те же результаты.

Вот версия SP, это было изменено немного из-за проблем IP. Я надеюсь, что это все еще имеет смысл:

SELECT 
t1.pkiOrderID,
t1.fkiBasketId,
t1.sOriginBasketCode,
t1.dtDateCreated,
t1.sOrderCode,
t1.fkiUserCde,
t1.fkiOrgCde,
t1.sApprovalPerson,
t1.dtDateApproved,
t1.sRequestNo,
t1.dtRequiredDate,
t1.Requestor,
t1.OnBehalfOf,
t1.OrderDesc,
t1.OrderTypeId,
t1.fkiAgentID,
t1.fkiAgentRegionID,
stat.iStatus,
count(oi.pkiOrderItemId) as OrderItems,
count(wf.fkiOrderId) as WorkflowCount,
t1.Currency_Id,
t1.ExchangeRate,
t1.ref_odr_idn,
t2.sOrderCode as ref_odr_cde,
t1.ref_rfq_nbr,
t1.ref_rfs_nbr,
t1.ref_doc_nbr,
t1.ref_rsn,
t1.ref_forip_cde,
t1.ref_fa_nbr,
t1.odr_sub_typ
FROM    tbl1 t1 INNER JOIN 
tbl1Status stat ON
t1.pkiOrderID = stat.fkiOrderID AND
stat.dtDateStatusChanged = (SELECT MAX(stat2.dtDateStatusChanged) 
FROM tbl1Status stat2
WHERE stat2.fkiOrderId = t1.pkiOrderID) LEFT OUTER JOIN 
tbl1Item oi ON
t1.pkiOrderID = oi.fkiOrderId LEFT OUTER JOIN
tbl1Workflows wf ON
t1.pkiOrderID = wf.fkiOrderId LEFT OUTER JOIN 
tbl1 t2 ON 
t1.ref_odr_idn = t2.pkiOrderID
WHERE (t1.fkiUserCde = 'x'
or t1.fkiUserCde in (select fkiUserCde from tbl1 where fkiOrgCde in 
(select sys_org_cde from tbl3 t3 where t3.sys_lnk_org_cde = '123')))
AND ((t1.fkiOrgCde = '123'
and ('123' not in (select sys_org_cde from tbl3 t3) 
or (t1.OrderTypeID <     1 or stat.iStatus IN (2,3,4,5,6,7))))
OR (t1.fkiOrgCde in (select sys_org_cde from tbl3 t3 where     t3.sys_lnk_org_cde = '123')
and t1.OrderTypeID = 1 
and stat.iStatus NOT IN (2,3,4,5,6,7)))           
          AND   t1.OrderTypeID = 2

        GROUP BY
            t1.pkiOrderID,
            t1.fkiBasketId,
            t1.sOriginBasketCode,
            t1.dtDateCreated,
            t1.sOrderCode,
            t1.fkiUserCde,
            t1.fkiOrgCde,
            t1.sApprovalPerson,
            t1.dtDateApproved,
            t1.sRequestNo,
            t1.dtRequiredDate,
            t1.Requestor,
            t1.OnBehalfOf,
            t1.OrderDesc,
            t1.OrderTypeId,
            t1.fkiAgentID,
            t1.fkiAgentRegionID,
            stat.iStatus,
            t1.Currency_Id,
            t1.ExchangeRate,
            t1.ref_odr_idn,
            t2.sOrderCode,
            t1.ref_rfq_nbr,
            t1.ref_rfs_nbr,
            t1.ref_doc_nbr,
            t1.ref_rsn,
            t1.ref_forip_cde,
            t1.ref_fa_nbr,
            t1.odr_sub_typ
        ORDER BY t1.dtDateCreated DESC

Извините за форматирование. Я изо всех сил пытался получить его читаемый вообще на форуме.

7
задан Johann Strydom 6 July 2010 в 14:57
поделиться

2 ответа

Поскольку мой комментарий, казалось, давал правильный ответ, я решил превратить его в полный ответ для потомков в духе stackoverflow.

Вероятно, ваша проблема вызвана анализом параметров SQL Server . Чтобы предотвратить это, просто присвойте значения входящих параметров другим переменным, объявленным прямо в верхней части SP.

См. Эту красивую статью об этом

Пример:

CREATE PROCEDURE dbo.MyProcedure
(
    @Param1 INT
)
AS

declare @MyParam1 INT
set @MyParam1 = @Param1

SELECT * FROM dbo.MyTable WHERE ColumnName = @MyParam1 

GO

Я скопировал эту информацию с eggheadcafe.com .

Редактировать: Согласно комментарию Иоганна Стридома, вот еще один вариант: Оптимизируйте запросы, управляемые параметрами, с помощью SQL Server. ОПТИМИЗИРУЙТЕ ПО подсказке .

21
ответ дан 6 December 2019 в 07:24
поделиться

Только что воссоздал сохраненный процесс и исправил его. Действительно, очень странно.

3
ответ дан 6 December 2019 в 07:24
поделиться