11

私はこれがコードのいくつかの場所に表示されるのを見ましたが、説明はなく、その上に不可解なコメントがあります(コンテキストのアイデアのために宣言と実行が含まれています。これはSqlCommandを実行するための標準的な手順です)。

//SqlCommand cmd = new SqlCommand();
//cmd.ExecuteReader();
//Read off the results

//Cancel the command. This improves query time.
cmd.Cancel ();

基本的に、クエリを終了すると、元に戻ってキャンセルし、パフォーマンスが向上したと主張します。XmlReaderが解放されたときにメモリが戻ってくる可能性があると思いますが、通常はとにかくスコープから外れようとしています。

私はこれまで気にしたことがありませんが、レビューしているコードにようやく現れました。コードで実行した後にSqlCommandをキャンセルすると、実際にはどういうわけかスピードアップしますか、それともこれは単なる奇妙なプログラマーの迷信ですか?

4

4 に答える 4

16

MSDNによると、これは正しいです。

Closeメソッドは、出力パラメーター、戻り値、およびRecordsAffectedの値を入力し、大規模または複雑なクエリの処理に使用されたSqlDataReaderを閉じるのにかかる時間を増やします。戻り値とクエリの影響を受けるレコード数が重要でない場合は、Closeメソッドを呼び出す前に関連するSqlCommandオブジェクトのCancelメソッドを呼び出すことで、SqlDataReaderを閉じるのにかかる時間を短縮できます。

変!

于 2010-08-17T19:11:11.650 に答える
9

呼び出しが多数の行を返し、すべての行を読み取らない場合、呼び出しによってパフォーマンスが大幅に向上Cancelする可能性があります。ExecuteReader

たとえば、クエリが100万行を返し、最初の1000行だけを読み取った後でリーダーを閉じたとします。Cancelリーダーを閉じる前に呼び出しに失敗すると、Closeメソッドはブロックされ、残りの999,000行を内部的に列挙します。

試してみてください!

于 2013-06-20T03:41:52.293 に答える
0

Cinchcastの技術チームがベンチマークを実施しましたが、cmd.Cancel()を追加すると実際に速度が低下することがわかりました。

ホストのエピソードのリストを取得するDALC呼び出しがあります。1000回実行し、平均応答時間を取得して10エピソードを返しました。

したがって、10のショーを返すと、キャンセルありの平均:0.069sキャンセルなしの平均:0.026s

10エピソードを返すことで実行すると、かなり大幅に遅くなります。

そこで、100エピソードを返すことで再試行し、より大きな結果セットが違いを生むかどうかを確認しました。

したがって、各呼び出しで100の番組を返す場合、キャンセルありの平均:0.132秒キャンセルなしの平均:0.122秒

したがって、今回は時間の差がはるかに小さかった。通常のユースケースではキャンセルを使用しなくても、さらに高速です。

于 2012-09-13T15:53:31.620 に答える
0

この例では、リーダーを開き、すべての行を読み取り、[キャンセル]コマンドを実行しましたが、リーダーが閉じられていた場所は表示されませんでした。

/のにキャンセルが発生することを確認してください。たとえば、この例ではパフォーマンスが向上しません(残念ながら、本番環境の実際のコード)。DisposeClose

using (var rdr = cmd.ExecuteReader (CommandBehavior.Default))
{
   retval = DocumentDir.DBRead (rdr);
}

// Optimization.  Allows reader to close more quickly.... NOT!
cmd.Cancel ();  // bad!

残念ながら、Usingステートメントによってすでに閉じられています。

これは、潜在的なメリットを実現するために読むべき方法です。

using (var rdr = cmd.ExecuteReader (CommandBehavior.Default))
{
   retval = DocumentDir.DBRead (rdr);

   // Optimization.  Allows reader to close more quickly.
   cmd.Cancel ();
}

MSDN SqlCommand.Cancelから:

まれに、ExecuteReaderを呼び出してからCloseを(暗黙的または明示的に)呼び出してからCancelを呼び出し、次にCancelを呼び出すと、キャンセルコマンドがSQL Serverに送信されず、Closeを呼び出した後も結果セットがストリーミングを継続できる場合があります。 。これを回避するには、リーダーまたは接続を閉じる前に、必ずキャンセルを呼び出してください。

于 2014-08-14T00:06:05.660 に答える