【问题标题】:SQL Server Performance in ADO.NET vs SSMSADO.NET 与 SSMS 中的 SQL Server 性能
【发布时间】:2013-01-09 21:51:59
【问题描述】:

在开始之前,我在这里阅读了几篇关于过去性能问题的帖子,人们在 ADO 和 SSMS 中执行 SQL 语句/过程。我花了一天的大部分时间试图自己解决这个问题...重新索引,使用sp_recompile,将Option(Recompile) 添加到我的程序中。没有任何效果,所以我正在向社区寻求帮助。

我有一个存储过程,我的一个 Web 应用程序执行该存储过程来运行报告。特别是这个过程主要由动态 SQL 组成,以允许返回不同的报告结果......我网站上的一种动态报告功能。无论如何,一些报告可以运行(使用相同的程序)并且结果几乎立即返回。但是,可以使用其他选项,并且该过程可能需要几分钟才能运行。但是,使用 SSMS 中的相同选项手动运行该过程会立即产生结果。这听起来像是某种计划缓存问题,但在重新编译程序并添加 WITH(RECOMPILE) 后,它在 ADO.NET 中的运行速度仍然非常慢。

所以我开始查看 SQL 配置文件,也许 ADO 正在使用的“SET”命令之一导致了这个问题。但是,在使用完全相同的 SET 命令后,它仍然几乎可以立即使用 SSMS 返回。

我尝试使用DBCC freeproccacheDBCC freesystemcache 清除所有存储的计划,但这也没有帮助。

我尝试的另一件事是获取在过程中生成的动态 SQL,并直接在 SqlCommand 语句中运行它。这里没有参数,只是简单的 SQL。再次,它在 SSMS 中立即运行,但在 ADO.NET 中需要永远。

有没有办法(运行 ADO.NET)查看生成的计划?我可以在 SSMS 中执行此操作,但这对我没有帮助,因为它在 SSMS 中运行良好。

如果有任何帮助,这里是原始 SQL 语句...

SELECT sf.ID [FileID], sb.ID [BillID], sb.Client_BillID, sf.BobID [ClientID], c.Name [ClientName], c.Parent_ID [ParentID], pnt.Name [ParentName], Network_ID, Facility_Name, OON, sb.TaxID, Inpatient, sf.ProcessDate, sb.Reversed, sb.State, sb.Product, sb.FormType, n.Direct 
INTO #t1 FROM SubmitterFiles sf WITH(NOLOCK) 
INNER JOIN SubmitterBills sb WITH (NOLOCK) ON sf.ID = sb.FileID 
LEFT JOIN PPORecords r WITH (NOLOCK) ON sb.RecordID = r.ID 
LEFT JOIN PPONetworks n WITH (NOLOCK) ON r.Network_ID = n.ID 
LEFT JOIN PPOProviders p WITH (NOLOCK) ON r.Provider_ID = p.ID 
INNER JOIN Clients c WITH (NOLOCK) ON sf.BobID = c.ID 
LEFT JOIN Clients pnt WITH (NOLOCK) ON c.Parent_ID = pnt.ID 
WHERE sf.ProcessDate BETWEEN 'Dec  1 2012 12:00AM' and 'Dec 31 2012 12:00AM' 
AND ISNULL(sb.Status,'') NOT IN ('E','V') 
AND (c.Parent_ID IN (1989) or c.ID  IN (1989)) 
; 

SELECT TOP 100 0 as [placeholder],NULL AS BillID, NULL AS Client_BillID, NULL AS DOS
,NULL AS Network_ID
,NULL AS Client_ID
,NULL AS Client_Name
,NULL As ProcessDate
,NULL As ProcessMonth
,NULL AS SubClientID
,NULL AS SubClientName
,Product
,TaxID
, FacilityName
, LastName
, FirstName
,State
,County
,NULL As ProcCode
,NULL As FormType
,NULL As Inpatient, NULL AS Outpatient
,COUNT(DISTINCT sb.BillID) AS [Total_Bills]
,SUM(sl.Amount) AS  [Total_Charges]
,SUM(sl.StateSavings) AS [Total_StateSavings]
,SUM(sl.PPOSavings) AS [Total_PPOSavings]
,COUNT(DISTINCT TaxID) AS [Total_Unique_TaxIds]
,0,0,0,0,0
,COUNT(DISTINCT CASE WHEN sb.OON = 1 THEN sb.BillID ELSE NULL END) AS [Out_Bills]
,SUM(CASE WHEN sb.OON = 1 THEN sl.Amount ELSE 0 END) AS [Out_Charges]
,SUM(CASE WHEN sb.OON = 1 THEN sl.StateSavings ELSE 0 END) AS [Out_StateSavings]
,COUNT(DISTINCT CASE WHEN sb.OON = 1 THEN sb.TaxID ELSE NULL END) AS [Out_Unique_TaxIds]
,0,0,0,0,0
,0,0,0,0,0
 FROM SubmitterLines sl  WITH (NOLOCK, INDEX(IX_SubmitterLines_BillID))
 INNER JOIN #t1 sb WITH(NOLOCK) ON sl.BillID = sb.BillID
 INNER JOIN SubmitterBillProviders sbp WITH(NOLOCK) ON sb.BillID = sbp.ID
 INNER JOIN SubmitterBillZipCounty sbc WITH(NOLOCK) ON sb.BillID = sbc.ID
 WHERE 1 = 1
GROUP BY Product
,TaxID
,FacilityName, LastName, FirstName
,State
,County
ORDER BY [Out_Bills] DESC

【问题讨论】:

  • 在标题ADO 在标签ADO.NET。请正确。
  • 我强烈建议放弃存储过程中的动态 SQL,否则执行计划将始终不是任务的最佳选择。类似于 SQL 在执行标量函数时无法很好地计划,动态 SQL 总是会令人惊讶,系统将难以优化其执行。
  • Darth - 动态 SQL 占有一席之地。我知道这不会是最佳的,但它似乎不是当前问题的原因。提取 SQL 并执行仍然会重现问题。
  • 您是否尝试过添加查询提示OPTION (OPTIMIZE FOR UNKNOWN)
  • @YS。 - 我刚刚尝试过,但没有任何区别。

标签: sql-server sql-server-2008 ado.net


【解决方案1】:

这是昨晚让我睡不着觉的问题之一,所以我又开始重新审视所有事情。最终让我感到震惊的是,在 SSMS 中,我将默认行数设置为 1000。虽然我在 SQL Profiler 中运行跟踪时遇到了什么样的错误,但其他 SET 并没有显示出来。将 ROWCOUNT 设置回 0 可以让我在 SSMS 中重现这一点,让我可以查看执行计划并修复导致查询运行缓慢的问题。

归根结底,这不是 ADO 问题 - 这是我在 SSMS 中设置的,用于限制我通常希望返回的行数。由于我的部分查询构建了一个更大结果集的临时表,因此该临时表仅填充了 1000 行。

【讨论】:

  • 来自此处msdn.microsoft.com/en-us/library/ms188774.aspx 的未来读者的相关说明:显然,Microsoft 正在 SQL Server 的未来版本中对此进行一些更改:“使用 SET ROWCOUNT 不会影响 DELETE、INSERT 和 UPDATE 语句SQL Server 的下一个版本。避免在新的开发工作中将 SET ROWCOUNT 与 DELETE、INSERT 和 UPDATE 语句一起使用,并计划修改当前使用它的应用程序。"
【解决方案2】:

你看过这个 SO 线程吗? SQL Server query runs slower from ADO.NET than in SSMS

如已接受的答案中所建议的那样,Showplan XML 事件类可以工作吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多