それは私が直面したインタビューの質問に基づいています。
非常に短い定義は
クエリによって返される行を操作するために使用できます。
カーソルの使用に加えて(ポイントは here MSDNにリストされています)、クエリまたはストアドプロシージャを使用してすべての操作を実行できる場合(私が間違っていなければ、 Transact-SQL for ms-sqlを使用できるように)、カーソルを使用する必要がある具体的なポイントはありますか?
大きな結果セットと比較してカーソルを使用することは、一気にビデオをダウンロードし、ダウンロード後に見るのではなく、ビデオストリーミングを使用するようなものです。ダウンロードする場合、ダウンロードが終了するまで待機するためのスペースと忍耐が必要です。これで、マシンやネットワークがどれほど高速であっても、誰もが同じ速度で映画を見ることができます。
通常、クエリはサーバーに送信されて実行され、結果セットがネットワーク経由で1回のバーストで送信されます。カーソルを使用すると、行ごとにデータにアクセスでき、要求した場合にのみすべての行をストリーミングできます(実際に表示できます)。
ただし、次の点に注意してください。
一貫性:カーソルを使用して、データの一貫したスナップショットではなく(通常)操作します。したがって、同時実行/一貫性/分離は、データベース全体(ACID)から1行のみに保証されます。通常、DBMSにどのレベルの同時実行性を要求するかを通知できますが、細心の注意(現在のテーブル全体をロックしている)である場合、サーバー側のリソース節約の多くを破棄します。
すべてのパケットを送信することは非常に効率が悪い場合があります。すべてのパケットにはネゴシエーションのオーバーヘッドがあり、パケットごとに圧縮された大きなデータチャンクを送信することで回避できるためです。 (すべての行を個別に送信するのに十分なDBサーバーまたはクライアントライブラリはありません。両端にキャッシュとチャンクがありますが、それでも関連があります。)
カーソルを正しく実行するのは困難です。集計関数でGROUP BY句を使用する、カーソルを使用する動機付けとなる大きな結果セットを持つクエリを検討してください。 (このようなクエリはデータウェアハウスでは一般的です)。 GROUP BYは、結果セット全体を一度に生成して保存する必要があるため、サーバーを完全に破壊する可能性があります。他のテーブルのロックを保持している場合もあります。
経験則:
「シーケンシャルな性質」とは、クエリの重いGROUP BY句に集約関数がないことを意味します。サーバーは、カーソルがキャッシュから消費する間に10行を計算し、その間に他の処理を行うことを遅延的に決定できます。
HTH
カーソルは、セット内のレコードを繰り返すことができるツールです。 orderとcurrent recordの概念があります。
一般に、SQL
はマルチセットで動作します。これらは、全体としてとられた順序なしで繰り返しレコードのセットである可能性があります。
たとえば、次のクエリ:
SELECT *
FROM a
JOIN b
ON b.a = a.id
、マルチセットa
およびb
で動作します。
このクエリでは、レコードの順序、レコードの保存方法、アクセスする順序などについて何も仮定していません。
これにより、実装の詳細を抽象化し、システムがこのクエリを実行するために最適なアルゴリズムを選択できるようにします。
ただし、すべてのデータを変換した後、最終的には順番に1つずつレコードにアクセスする必要があります。
電話帳のエントリがハードドライブにどのように保存されるかは気にしませんが、プリンタではアルファベット順にフィードする必要があります。書式タグは各レコードに個別に適用する必要があります。
それがまさにカーソルが作用する場所です。クライアント側で結果セットを処理するたびに、カーソルを使用しています。サーバーからメガバイトのソートされていないデータを取得することはありません。小さな変数:結果セット記述子を取得し、次のように記述します。
while (!rs.EOF) {
process(rs);
rs.moveNext();
}
これがすべてあなたのためにこれを実装するカーソルです。
もちろん、これはデータベースとクライアントの相互作用に関するものです。
データベース自体については:insideデータベースでは、カーソルはほとんど必要ありません。前述したように、ほとんどすべてのデータ変換は集合演算を使用してより効率的に実装できるためです。
ただし、例外があります。
SQL Server
の分析操作の実装は非常に不十分です。たとえば、カーソルを使用すると、集合ベースの操作を使用するよりもはるかに効率的に累積合計を計算できますまた、この記事を読む価値があるかもしれません。
カーソルを使用すると、一連のデータをプログラムで順番に読み取ることができるため、SQLのセットベースの動作特性ではなく、従来のファイルアクセスと同様に動作します。
これが役立ついくつかの状況があります。
ファイルベースのレコードアクセス動作をシミュレートする必要がある場合-たとえば、データストレージにインデックス付きファイルを使用するために以前に記述されたコードのデータストレージメカニズムとしてリレーショナルデータベースが使用されている場合。
データを順番に処理する必要がある場合-簡単な例は、特定の顧客の現在の合計残高を計算することです。 (OracleやSQLServerなどの多くのリレーショナルデータベースには、この必要性を大幅に削減するSQLの分析拡張機能があります。)
必然的に、ウィキペディアにはもっとあります: http://en.wikipedia.org/wiki/Database_cursor
セットベースのロジックは、非常に複雑で不透明になる場合があります。これらの場合、およびパフォーマンスが問題にならない場合は、サーバー側カーソルを使用して、リレーショナルロジックをより管理しやすく使い慣れた(非リレーショナル思考者にとって)手続き型ロジックに置き換えて、メンテナンスを容易にすることができます。
カーソルを使用すると、一度に1行にアクセスできます。そのため、一度に1行だけで多くの行を操作する場合に使用すると便利です。
私は私のクラスで、カーソルを使用する理由は、メモリに収まるよりも多くの行にアクセスしたいので、すべての行をコレクションに入れてループすることはできないということです。