1. ホーム
  2. sql

[解決済み] なぜ人々はSQLカーソルを嫌うのか?[クローズド]

2022-07-13 22:36:51

質問

カーソルのオーバーヘッドや不便さからカーソルを使わないようにしたい気持ちはわかりますが、わざわざカーソルを使わないようにするカーソル恐怖症が深刻化しているようですね。

例えば、ある質問では、カーソルを使って明らかに些細なことを行うにはどうしたらよいかを尋ねており、受け入れられた答えは、処理できる行の数が32に制限されているにもかかわらず、共通テーブル式(CTE)再帰的クエリと再帰的カスタム関数の使用を提案しています(SQLサーバの再帰的関数呼び出し制限によります)。これは、単純なカーソルの使用を避けるために多大な労力を必要とすることは言うまでもなく、システムの寿命のためにひどい解決策であると私には思われます。

このレベルの非常識な憎悪の理由は何でしょうか? どこかの「著名な権威」がカーソルに対するファトワを発行したのでしょうか。カーソルの心には、子供たちのモラルを堕落させるような、言いようのない悪が潜んでいるのでしょうか?

Wikiの質問です。回答者よりも答えに興味があります。

関連情報です。

SQL Server Fast Forward Cursors

EDIT: もっと正確に言わせてください。私は、以下のことを理解しています。 カーソルは通常のリレーショナル操作の代わりに使用すべきではありません。 それは当然のことです。私が理解できないのは、カーソルがより単純でより効率的な解決策であるにもかかわらず、まるで疥癬か何かを持つようにカーソルを避けるためにわざわざ遠くまで行く人々です。私を困惑させるのは非理性的な憎悪であって、明らかな技術的効率性ではありません。

どのように解決するのですか?

カーソルによるオーバーヘッドは、単にAPIの一部に過ぎません。 カーソルは、RDBMS の一部がどのように機能するかを示しています。 多くの場合 CREATE TABLEINSERT がある SELECT ステートメントがあり、その実装は明らかな内部カーソル実装です。

より高いレベルの"セットベース演算子"を使用することは、カーソル結果を単一の結果セットに束ね、APIの行き来を少なくすることを意味しています。

カーソルは、ファーストクラスのコレクションを提供するモダンな言語より前にありました。 古い C、COBOL、Fortran などは、広く使用できるコレクションという概念がなかったため、一度に 1 つの行を処理する必要がありました。 Java、C#、Python などは、結果セットを格納するためのファーストクラスのリスト構造を持っています。

遅い問題

ある業界では、リレーショナルジョインは謎であり、人々は単純なジョインではなく、ネストしたカーソルを書きます。 本当に壮大なネストされたループ操作が、たくさんのカーソルとして書き出されるのを見たことがあります。 RDBMSの最適化に負ける。 そして、本当にゆっくりと実行されます。

ネストされたカーソル ループを結合と単一のフラットなカーソル ループに置き換えるために SQL を書き換えるだけで、プログラムを 100 分の 1 の時間で実行できるようになります。 [彼らは私を最適化の神だと思っていました。 私がやったのはネストしたループをjoinに置き換えただけなのに。 まだカーソルを使っていた]。

この混乱は、しばしばカーソルを非難することにつながります。 しかし、それはカーソルではなく、カーソルの誤用が問題なのです。

サイズの問題

本当に大きな結果セット(つまり、テーブルをファイルにダンプする)には、カーソルが不可欠です。 セットベースのオペレーションは、メモリ内の単一のコレクションとして本当に大きな結果セットを実体化することができません。

代替手段

私はできるだけORMレイヤーを使用するようにしています。 しかし、これには2つの目的があります。 第一に、カーソルは ORM コンポーネントによって管理されます。 2 つ目は、SQL がアプリケーションから設定ファイルに分離されることです。 カーソルが悪いわけではありません。 すべてのオープン、クローズ、フェッチをコーディングすることは、付加価値のないプログラミングだということです。