5

始める前に、ADO と SSMS で SQL ステートメント/プロシージャを実行した過去のパフォーマンスの問題に関するいくつかの投稿をここで読みました。私は自分でこの問題を解決しようとして一日の大部分を費やしました...インデックスの再作成、 の使用、手順へのsp_recompile追加。Option(Recompile)何も機能していないので、コミュニティに支援を求めています。

Web アプリケーションの 1 つがレポートを実行するために実行するストアド プロシージャがあります。特にこの手順は、さまざまなレポート結果が返されるようにするために、ほとんどが動的 SQL で構成されています...私のサイトの動的レポート機能のようなものです。とにかく、一部のレポートは (同じ手順を使用して) 実行でき、結果はほとんどすぐに返されます。ただし、他のオプションを使用することもでき、手順の実行には数分かかる場合があります。ただし、SSMS で同じオプションを使用して手順を手動で実行すると、すぐに結果が得られます。ある種のプラン キャッシュの問題のように思えますが、プロシージャを再コンパイルしてWITH(RECOMPILE).

そこで、SQL プロファイルを調べ始めました。おそらく、ADO が使用している「SET」コマンドの 1 つが問題を引き起こしているのでしょう。ただし、まったく同じ SET コマンドを使用した後でも、SSMS を使用するとすぐに返されます。

DBCC freeproccacheandを使用して、保存されている計画をクリアしようとしDBCC freesystemcacheましたが、これも役に立ちませんでした。

私が試したもう 1 つのことは、プロシージャで生成される動的 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
4

2 に答える 2

1

これは、昨夜私を眠らせなかった問題の 1 つであったため、すべてをもう一度やり直しました。最後に、SSMS では、デフォルトの行数が 1000 に設定されていることに気付きました。SQL プロファイラーでトレースを実行したときにどのようなバグが発生したかというと、これは他の SET では表示されませんでした。ROWCOUNT を 0 に戻すと、SSMS でこれを再現できるようになり、実行計画を確認して、クエリの実行が遅くなる問題を修正することができました。

結局のところ、これは ADO の問題ではなく、通常返す行数を制限するために SSMS に入れた設定でした。私のクエリの一部はより大きな結果セットの一時テーブルを作成するため、その一時テーブルには 1000 行しか入力されていませんでした。

于 2013-01-10T14:14:13.293 に答える
0

このSOスレッドを見たことがありますか?ADO.NET からの SQL Server クエリの実行は、SSMS よりも遅くなります

受け入れられた回答で提案されているように、Showplan XML Event Class は機能しますか?

于 2013-01-10T08:20:37.130 に答える