2

私が先に行きます。

私は 100% セット オペレーション キャンプに参加しています。しかし、目的の入力ドメイン全体に対するセット ロジックによって、クエリが大幅に遅くなったり、クロールになったり、基本的に無限の時間がかかったりするような大規模な検索が行われるとどうなるでしょうか?

これは、おそらく数十行 (私がターゲットにしている数百万行ではなく) のちょっとしたカーソル (または while ループ) を使用する 1 つのケースです。したがって、私はまだ (分割されたサブ) セットで作業していますが、検索はより高速に実行されます。

もちろん、さらに高速な解決策は、分割された入力ドメインを外部から並列に呼び出すことですが、それによって外部システムとの相互作用が発生し、直列にループすることで「十分な」速度を達成できる場合は、価値がないかもしれません。それ(特に開発中)。

4

10 に答える 10

3

There are lots of different cursor behaviors.

  • STATIC vs KEYSET vs DYNAMIC
  • SCROLL vs FORWARD ONLY vs FAST FORWARD
  • INSENSITIVE or not
  • OPTIMISTIC or READ ONLY or not
  • LOCAL vs GLOBAL (at least this is easy)

You should never use a cursor unless you can explain all of these options and which ones are on by default.

And so, I never do.

Instead, when I feel the urge to loop over something in T-SQL... I load it into a variable table, which is something like a LOCAL STATIC SCROLL cursor... except that it can be indexed and joined (edit: and the downside of preventing the use of parallelism).

于 2008-10-06T04:36:20.467 に答える
3

構成テーブルの行を読み取ってコードを生成して実行する必要がある場合や、多くのメタプログラミングシナリオで発生する場合がたくさんあります。

オプティマイザが十分に賢くないために、カーソルが単にパフォーマンスを上回っている場合もあります。そのような場合、テーブルのインデックスや統計を介してオプティマイザに単純に明らかにされないメタ情報が頭の中にあるか、コードが非常に複雑であるため、結合(および通常は再結合)が単純に可能です。カーソルベースの方法でそれらを視覚化できる方法で最適化されていません。SQL Server 2005では、CTEはコード内でこれを非常に単純に見える傾向があると思いますが、オプティマイザーがCTEをより単純であると見なすかどうかはわかりません。つまり、実行プランを実行計画と比較することになります。最も効率的に電話をかけます。

一般的な規則-必要な場合を除いて、カーソルを使用しないでください。しかし、必要に応じて、それについて自分自身に苦労しないでください。

于 2008-10-06T00:34:14.450 に答える
2

非常にまれに、カーソルを必要とする操作が発生しますが、T-SQLではかなりまれです。Identity(int)列またはシーケンスは、設定された操作内の方法で物事を順序付けます。特定のポイントで計算が変更される可能性のある集計(ゼロから制限または超過ポイントまでクレームを累積するなど)は本質的に手続き型であるため、これらはカーソルの候補です。

他の候補は、構成テーブルをループしたり、一連のクエリを生成して実行したりするなど、本質的に手続き型です。

于 2008-10-05T23:44:54.410 に答える
2

デビッドBが言ったことに加えて、私もループ/テーブルアプローチを好みます。

それが邪魔にならないように、カーソルとループ/テーブルアプローチの1つのユースケースには、非常に大規模な更新が含まれます。10億行を更新する必要があるとしましょう。多くの場合、これはトランザクションである必要はありません。たとえば、状況が悪化した場合にソースファイルから再構築できる可能性があるデータウェアハウスの集約である可能性があります。

この場合、更新は「チャンク」で行うのが最適な場合があります。おそらく、一度に100万行または1000万行です。これにより、リソースの使用量を最小限に抑えることができ、その10億行を更新しながら、マシンの同時使用を最大化できます。ここでは、ループ/チャンクアプローチが最適な場合があります。恒星に満たないハードウェアでの10億行の更新は、問題を引き起こす傾向があります。

于 2008-10-06T16:47:13.130 に答える
2

純粋な SQL 環境では、お勧めのようにカーソルを避けたいと思います。しかし、手続き型言語 (PL/SQL など) に移行すると、多くの用途があります。たとえば、特定の行を取得し、それを更新するよりも複雑なことを「実行」したい場合。

于 2008-10-05T20:19:31.127 に答える
2

確かに、セットベースの操作よりもカーソルの方が適している場所はたくさんあります。

1 つは、テーブル内の大量のデータを更新している場合 (スケジュールに従ってデータを事前計算する SQL エージェント ジョブなど)、カーソルを使用して、1 つの大きなセットではなく複数の小さなセットで実行して、同時ロックの量を減らし、データにアクセスする他のプロセスとのロック競合やデッドロックの可能性を減らします。

もう 1 つは、sp_getapplockストアド プロシージャを使用してアプリケーション レベルのロックを取得する場合です。これは、複数のプロセスによってポーリングされている行が 1 回だけ取得されるようにする場合に役立ちます (例 here )。

ただし、一般的には、可能であればセットベースの操作の使用を開始し、機能またはパフォーマンス上の理由で必要な場合にのみカーソルに移動するのが最善であることに同意します(後者を裏付ける証拠があります)。

于 2008-10-06T00:04:13.077 に答える
1

カーソルは、システム プロシージャを異なる入力値で複数回実行する場合にも便利です。システム プロシージャをセット ベースに書き換えるつもりはないので、その場合はカーソルを使用します。さらに、通常、非常に限られた数のオブジェクトを通過します。一度に 1 つのレコードのみを挿入する既存の proc で同じことを行うことができますが、実行するレコードが多数ある場合、パフォーマンスの観点から、これは通常悪いことです。セットベースになるように書き直します。

他の人が議論しているように、累計はより速くなる可能性があります。

データベースから電子メールを送信している場合 (最良のアイデアではありませんが、行き詰まっている場合もあります)、カーソルを使用すると、同じ電子メールを両方送信したときに、顧客 a が顧客 b の電子メール アドレスを確認できないようにすることができます。

于 2009-03-04T15:24:14.337 に答える
0

カーソルがセットよりも優れている操作の 1 つは、累計などを計算する場合です。

于 2008-10-05T20:02:27.667 に答える
0

なんらかの理由でテーブルがインデックス化されていない場合、カーソルは、テーブルを反復処理する他の方法よりも高速になります。この情報は、昨年の SQL Server のカーソルに関する ブログ投稿で見つけました。

著者は「最後の手段としてのみ使用する」アプローチを支持していますが (ここにいるすべての人がそうであるように)、カーソルが他の利用可能な代替手段と同様に機能するケースを 1 つまたは 2 つ見つけています (Robert Rossney によって指摘された実行中の合計を含む)。 . 彼女が指摘する他の興味深い点として、カーソルはアドホック クエリよりもストアド プロシージャ内でより効率的に動作することが挙げられます。著者はまた、カーソルに関連するパフォーマンスの問題がいつ発生し始めるかを指摘する優れた仕事をしています。

ブログ投稿には実際のコードが含まれているため、読者はクエリを自分で試して結果を確認できます。

于 2008-10-06T20:24:14.097 に答える
0

カーソルを使用しなければならないということは、通常、アプリケーションで行うべきことをデータベースで行っていることを示しています。他の人が言ったように、カーソルは通常、ストアド プロシージャが実行中の合計を計算するとき、またはコードやメタプログラミングを生成するときに必要です。

しかし、そもそもストアド プロシージャでそのような作業を行うのはなぜでしょうか。それは本当にデータベース サーバーの最適な使い方ですか? T-SQL は、コードを生成するときに使用する言語として本当に適切ですか?

確かに、答えが「はい」の場合もあれば、「いいえ」の場合もありますが、こちらの方が簡単です。私の見解では、物事をシンプルに保つことは、時期尚早の最適化よりも優先されます。だから私はカーソルを使います。しかし、私がカーソルを使う必要があると思ったとき、宇宙は、私が本当に適切な答えを持っているべきであるという質問を私に求めています.

于 2008-10-06T19:53:36.577 に答える