[解決済み] なぜ人々はSQLカーソルを嫌うのか?[クローズド]
質問
カーソルのオーバーヘッドや不便さからカーソルを使わないようにしたい気持ちはわかりますが、わざわざカーソルを使わないようにするカーソル恐怖症が深刻化しているようですね。
例えば、ある質問では、カーソルを使って明らかに些細なことを行うにはどうしたらよいかを尋ねており、受け入れられた答えは、処理できる行の数が32に制限されているにもかかわらず、共通テーブル式(CTE)再帰的クエリと再帰的カスタム関数の使用を提案しています(SQLサーバの再帰的関数呼び出し制限によります)。これは、単純なカーソルの使用を避けるために多大な労力を必要とすることは言うまでもなく、システムの寿命のためにひどい解決策であると私には思われます。
このレベルの非常識な憎悪の理由は何でしょうか? どこかの「著名な権威」がカーソルに対するファトワを発行したのでしょうか。カーソルの心には、子供たちのモラルを堕落させるような、言いようのない悪が潜んでいるのでしょうか?
Wikiの質問です。回答者よりも答えに興味があります。
関連情報です。
SQL Server Fast Forward Cursors
EDIT: もっと正確に言わせてください。私は、以下のことを理解しています。 カーソルは通常のリレーショナル操作の代わりに使用すべきではありません。 それは当然のことです。私が理解できないのは、カーソルがより単純でより効率的な解決策であるにもかかわらず、まるで疥癬か何かを持つようにカーソルを避けるためにわざわざ遠くまで行く人々です。私を困惑させるのは非理性的な憎悪であって、明らかな技術的効率性ではありません。
どのように解決するのですか?
カーソルによるオーバーヘッドは、単にAPIの一部に過ぎません。 カーソルは、RDBMS の一部がどのように機能するかを示しています。 多くの場合
CREATE TABLE
と
INSERT
がある
SELECT
ステートメントがあり、その実装は明らかな内部カーソル実装です。
より高いレベルの"セットベース演算子"を使用することは、カーソル結果を単一の結果セットに束ね、APIの行き来を少なくすることを意味しています。
カーソルは、ファーストクラスのコレクションを提供するモダンな言語より前にありました。 古い C、COBOL、Fortran などは、広く使用できるコレクションという概念がなかったため、一度に 1 つの行を処理する必要がありました。 Java、C#、Python などは、結果セットを格納するためのファーストクラスのリスト構造を持っています。
遅い問題
ある業界では、リレーショナルジョインは謎であり、人々は単純なジョインではなく、ネストしたカーソルを書きます。 本当に壮大なネストされたループ操作が、たくさんのカーソルとして書き出されるのを見たことがあります。 RDBMSの最適化に負ける。 そして、本当にゆっくりと実行されます。
ネストされたカーソル ループを結合と単一のフラットなカーソル ループに置き換えるために SQL を書き換えるだけで、プログラムを 100 分の 1 の時間で実行できるようになります。 [彼らは私を最適化の神だと思っていました。 私がやったのはネストしたループをjoinに置き換えただけなのに。 まだカーソルを使っていた]。
この混乱は、しばしばカーソルを非難することにつながります。 しかし、それはカーソルではなく、カーソルの誤用が問題なのです。
サイズの問題
本当に大きな結果セット(つまり、テーブルをファイルにダンプする)には、カーソルが不可欠です。 セットベースのオペレーションは、メモリ内の単一のコレクションとして本当に大きな結果セットを実体化することができません。
代替手段
私はできるだけORMレイヤーを使用するようにしています。 しかし、これには2つの目的があります。 第一に、カーソルは ORM コンポーネントによって管理されます。 2 つ目は、SQL がアプリケーションから設定ファイルに分離されることです。 カーソルが悪いわけではありません。 すべてのオープン、クローズ、フェッチをコーディングすることは、付加価値のないプログラミングだということです。
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] MySQLでコマンドラインを使用してSQLファイルをインポートするにはどうすればよいですか?
-
[解決済み] SQLテーブルで重複する値を検索する
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] SQLのSELECTでIF...THENを実行するにはどうすればよいですか?
-
[解決済み] SQLの複数列の順序付け
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
-
[解決済み] SQL ServerでINNER JOINを使用して削除するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
SQLラーニングノート--オペランドには1つのカラムが必要です。
-
MySQL】1136 - 列数が1行目の値数と一致しない問題を解決
-
MHAの高可用性構成とフェイルオーバー
-
[解決済み] ストアドプロシージャ 'dbo.aspnet_CheckSchemaVersion' が見つかりませんでした。
-
[解決済み] UNIONとUNION ALLの違いは何ですか?
-
[解決済み] JOINとINNER JOINの違いについて
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] 項目xにアクセスできるように文字列を分割するにはどうすればよいですか?
-
[解決済み] Count()で条件を指定することは可能ですか?
-
[解決済み] クエリが返す各行に対してストアドプロシージャを1回ずつ実行するにはどうすればよいですか?