注:この投稿は元々、eBook、SQLServerの高性能テクニック第3巻でのみ公開されていました。eBookについてはこちらをご覧ください。
3年以上前に、SQL Serverのカーソルオプションと、デフォルトをオーバーライドする必要がある理由について投稿しました。
- さまざまなカーソルオプションがどのような影響を与える可能性がありますか?
繰り返しになりますが、フォローアップを投稿したかったのですが、デフォルトを受け入れるだけではいけませんが、シナリオに最も適したオプションを実際に検討する必要があります。また、その投稿のコメントで出てきたいくつかの項目を明確にしたいと思いました。
Andrew Kellyは素晴らしい点を指摘しました。それは、STATIC
ということです。 カーソルは結果の1回限りのコピーを作成し、それらをtempdbに配置して、DYNAMIC
に影響を与える可能性のある同時実行の問題を回避します。 カーソル。すべての場合において、1つのオプションが他のオプションよりも明確な勝者ではありません。たとえば、多数のカーソル(または非常に大きな結果セットを持つカーソル)や、すでに過負荷になっているtempdbがあり、そこに追加のストレスをオフロードしたくない場合があります。しかし、それはテストする価値のあるものです。
ファビアーノはまた、DYNAMIC
およびFAST_FORWARD
カーソルはできます Hallowe'en問題に対して脆弱である(ここから始まる4部構成のシリーズでPaul Whiteによって議論された)。 Paulは、FAST_FORWARD
についてもコメントしました。 オプティマイザーが静的プランと動的プランのどちらを選択したかによっては、問題に対して脆弱ではない可能性があります(MicrosoftのMarc Friedmanがここで詳細に説明しています)。
最後に、すべてのデフォルトカーソルが同じように作成されるわけではないことを指摘したいと思います。いくつかのテストを実行し、SQL Serverがさまざまなシナリオ(sys.dm_exec_cursors
を使用して検証)でカーソルオプションを設定する方法を確認しました。 動的管理機能)。コードは非常に単純です:
DECLARE c CURSOR FOR [...blah blah...]; SELECT properties FROM sys.dm_exec_cursors(@@SPID);
テストしたシナリオの結果は次のとおりです。
カーソルクエリは… | に基づいていますタイプ | 並行性 | スコープ |
---|---|---|---|
定数(FOR SELECT 1 またはFOR SELECT SYSDATETIME() ) | 読み取り専用 | ||
#temp/##tempテーブル | 動的 | ||
ユーザーテーブル/ビュー | 動的 | ||
カタログビュー/DMV | 読み取り専用 | ||
結合#tmp->ユーザーテーブル/ビュー | 動的 | ||
参加#tmp->カタログビュー/DMV | 読み取り専用 | ||
結合ユーザーテーブル/ビュー->カタログビュー/DMV | 読み取り専用 |
クレジットが必要なクレジット–この調査は、StackOverflowに関するJeroenMostertからの回答によってトリガーされました。
したがって、カーソルのデフォルトオプションは、オーバーライドしない場合、カーソルの基になるクエリによって異なる場合があることに注意してください。いずれかまたはすべての場合に特定の動作を期待している場合は、必要なオプションを明示的に指定する習慣を身に付けてください。
しかし、実際には、要点は…
…カーソルの使用を停止します。今日、最良の解決策がカーソルである問題はほとんどありません。特にSQL Server 2012以降を使用している場合は、ウィンドウ関数の拡張機能を使用して、従来カーソルで解決されていたほぼすべての問題を解決できます。それでもカーソルを使用する必要があると思われる場合は、この投稿とその前身のアドバイスに従って、使用するオプションを決定してください。