sql >> データベース >  >> RDS >> Database

カーソルオプションのフォローアップ

    注:この投稿は元々、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以降を使用している場合は、ウィンドウ関数の拡張機能を使用して、従来カーソルで解決されていたほぼすべての問題を解決できます。それでもカーソルを使用する必要があると思われる場合は、この投稿とその前身のアドバイスに従って、使用するオプションを決定してください。


    1. PostgreSQLで文字列を分割する方法

    2. テーブル列の結果からSQLカスタムテキストを表示する

    3. PostgreSQLで(タイムゾーンなしで)現在の日付と時刻を取得する方法

    4. MySQLとMariaDBのすべてのデータベースを一覧表示および表示するSQLコマンド