2013-01-09 43 views
5

在我開始之前,我已經閱讀了幾篇關於過去的性能問題的人在ADO和SSMS中執行SQL語句/過程的文章。我花了一天的更好的一部分試圖解決這個問題,我自己... reindexing,使用sp_recompile,加入Option(Recompile)我的程序。沒有任何工作,所以我轉向社區尋求幫助。ADO.NET vs SSMS中的SQL Server性能

我有一個存儲過程,我的一個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 
+2

標題'ADO.NET'中的'ADO'標題。請正確。 –

+1

我強烈建議在您的sproc中放棄動態SQL,否則執行計劃對於任務來說總是不理想。與SQL在執行標量函數時無法很好地計劃類似,動態SQL將永遠是一個驚喜,系統將難以優化其執行。 –

+1

達思 - 動態SQL有它的地方。我知道這不會是最佳的,但它似乎不是當前問題的原因。提取SQL並執行仍會再現問題。 – Brosto

回答

1

這是昨天晚上讓我起牀的那些問題之一,所以我開始再次檢查一切。最後,我發現在SSMS中,我的默認行數設置爲1000.當我在SQL Profiler中運行一個跟蹤時,我遇到了什麼樣的錯誤,但是沒有與其他SET一起顯示。將ROWCOUNT設置回0允許我在SSMS中重現此操作,這樣我可以查看執行計劃並解決導致查詢運行緩慢的問題。

在一天結束時,它不是一個ADO問題 - 這是一個設置,我把SSMS中的行數限制在我通常喜歡返回的行數上。由於我的部分查詢構建了一個較大結果集的臨時表,因此該臨時表僅填充了1000行。

+1

來自這裏的未來讀者的相關說明http://msdn.microsoft.com/en-us/library/ms188774.aspx:顯然,Microsoft在SQL Server未來版本中對此進行了一些更改:「使用SET ROWCOUNT不會影響DELETE,INSERT和UPDATE語句在下一個版本的SQL Server中避免在新的開發工作中對DELETE,INSERT和UPDATE語句使用SET ROWCOUNT,並計劃修改當前使用它的應用程序。 – Kprof

+0

@Kprof - 感謝您指出。 – Brosto