31

署名付きのT-SQLストアドプロシージャがあります

CREATE PROCEDURE MyProc
@recordCount INT OUTPUT
@param1 INT
...

SQL Serverで直接実行すると、プロシージャは5秒未満で実行され、合計で約100行になるいくつかの結果セットが返されます。

ADO.NETSqlDataAdapter.Fillメソッドを使用してこのプロシージャを呼び出してaを設定DatasetするSqlTimeoutExceptionと、SqlCommand3分後(指定されたタイムアウト間隔)にが発生します。

ストアドプロシージャを変更して、出力パラメータがなくなり、必要な出力値が最後の結果セットとして返されるようにすると、問題が解決し、すべてが期待どおり5秒未満で実行されます。

しかし、なぜ?

問題を本当に解決したかどうかを理解せずに、コードベースを調べて、このタイプの動作のすべてのインスタンスを変更したくありません。

もう1つの注意点は、これは1つの特定のサーバーでのみ明らかであり、私たちが実行している他の同様のデータベースよりも大きなデータセットを持っていることは確かです。確かにSQLServerの設定ではありませんか?

アップデート

フレームワークソースにステップインすると、問題はメタデータの取得にあるようです。オブジェクトのConsumeMetaDataメソッドはSqlDataReader無期限にハングします。ただし、他のデータベースでテストを実行したため、再現できないため、このプロシージャがADO.NETを介して呼び出された場合のデータベース固有の問題です...すばらしい。

更新II

OleDbDataAdapterSQLOLEDBまたはSQLNCLIプロバイダータイプでを使用するようにコードを変更しても、問題が引き続き発生することを確認しました。間違いなく接続と関係があります。

4

3 に答える 3

48

問題の根本にあるのはADO.NET接続であると判断すると、このスレッドが答えにつながりました。

基本的に、SQL Server Management Studio(SSMS)を介した接続には、デフォルトでSETがありARITHABORT ONます。ADO.NET接続はそうではありません。

ARITHABORT OFFSSMSを介してクエリを直接設定および実行すると、同じように応答時間が遅くなります。

この設定の有無にかかわらず実行する場合の主な違いは、2つの呼び出しに対して異なるクエリプランが作成されることです。の場合、SSMSコマンドARITHABORTOFF、ADO.NET接続が使用していたコンパイル済みのキャッシュクエリプランを使用するため、タイムアウトになります。

データベースの管理者として次のコマンドを実行すると、設定に関係なく、すべてのクエリが期待どおりに実行されARITHABORTます。

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

コンパイルされたクエリプランが破損しているか、無効になっているとしか考えられません。

私は他のスレッドの解決策としてこれを使用します(私は答えに賛成しました)

ありがとう。

于 2009-05-08T09:45:03.657 に答える
1

私は正直に立っています-はい、あなたは両方を持つことができます-OUTPUTパラメータと返される行のセットあなたは毎日何か新しいことを学びます:-)

タイムアウトが発生する理由については-うーん....わかりにくいです。簡単な小さなサンプルは私にとってはうまくいきます。ストアドプロシージャ(少なくともその関連ビット)を投稿できますか?

ここに返される行はいくつありますか?

ストアドプロシージャのどの時点で、OUTPUTパラメータとして返す必要のある行数を計算していますか?

MaxRowsテストとして1つのSProcに別のパラメーターを追加し、データに対してを実行しようとするとどうなりSELECT TOP (@MaxRows).......ますか?それはすぐに戻りますか?

マーク

于 2009-05-07T11:34:34.930 に答える
0

つまり、SQL Serverがそれ自体を理解できない場合に、最も適切なインデックスを使用してlob論理読み取りを制限するように強制することで、問題を修正しました。

長い間-

私はこの問題に遭遇し、他のすべての提案された答えを試した後、別の方法でそれを解決しました。SSMSでは、クエリは約3秒で実行されていましたが、.NetMVCWebアプリケーションから呼び出されたときにタイムアウトになりました。

SSMSの統計IO出力は、1つのテーブルに195,500,000を超えるLOB論理読み取りがあったことを示していました(クラスター化列ストアインデックスを持ち、行インデックスもありますが、「LOB」列はありません)。実行プランから、負荷の大部分(76%)が行インデックスの1つでのインデックスシークから発生していることに気付きました。私は以下を使用しました:

from [table] with (index([clustered columnstore index name]))

クエリでクラスター化列ストアインデックスの使用を強制すると、クエリが1秒未満に減少し、LOB論理読み取りが1億9500万を超えるから6k未満に低下しました。現在、WebアプリからSPを呼び出すと、ラウンドトリップが発生します。 1.3秒。

オプションの再コンパイル、arithabortの設定、パラメーターのスニッフィングを試しましたが、最終的にSQLServerは使用するインデックスを特定できませんでした。これはあまりにもエッジケースであり、このデータベースでインデックスを強制する必要があるのはこのときだけです。

于 2016-10-24T16:15:46.477 に答える