【发布时间】:2011-03-12 08:34:33
【问题描述】:
我在 SQL Server 2000 上有一个存储过程,它采用 3 个参数。当我使用 SqlCommand.ExecuteReader () 从 DotNet 调用存储过程时,大约需要 28 秒。
当我直接在 SSMS 中运行相同的查询时,它会立即返回。
当我从存储过程中取出查询并使用 DotNet 直接运行它时,它也会立即返回。
这些是 SQL Profiler 会话的结果
SP Inside Dot Net
- 持续时间:28030
- 读取:2663365
- 写入:0
SSMS 中的 SP
- 持续时间:450
- 读取:23535
- 写入:65
直接在点网内部查询
- 持续时间:360
- 读取:24865
- 写入:57
以下几点对我来说很突出:
- SSMS 和 Dot Net 中的直接查询的统计数据非常相似
- Dot Net SP 进行大量读取但没有写入
- 另外两个读取很少,但写入几次
任何帮助将不胜感激。
这是 SP 的略显模糊的版本:
我怀疑这是一个查询计划问题,因为即使我从 DotNet 反复运行它,我总是得到相同的结果。
这是由于 IP 问题而略有改动的 SP 版本。我希望它仍然有意义:
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
对格式问题感到抱歉。我很难让它在论坛上可读。
【问题讨论】:
-
分析器中的两个“文本”条目是否相同? DotNet 中的 SSMS 和 SP 之间的性能差异应该为零。您是否设置相同的参数?
-
很奇怪。你是否都传递了相同的参数 3 次?
-
耶。我实际上将分析器中的文本复制到 SSMS 中以确保它完全相同。
-
在 .Net 中运行后,您是否在 SSMS 中运行它?如果是这样,sql server 可能已经缓存了查询计划并且只是重用它。你可以在这里发布你的实际过程吗?
-
@Johann:这里有更多关于参数嗅探的信息。 elegantcode.com/2008/05/17/…你在不同的环境中运行时是否使用了不同的参数。编辑:哦,我知道已经有人问过了。 :)
标签: c# .net sql-server ado.net sql-server-2000