前述のように、データベースはセット操作用に最適化されています。文字通り、エンジニアは座ってそのデータベースを長時間デバッグ/チューニングしました。それらを最適化する可能性はかなり低いです。ディスクの読み取り/書き込みのバッチ処理、キャッシング、マルチスレッドなど、操作するデータのセットがある場合は、さまざまな楽しいトリックを試すことができます。また、一部の操作はオーバーヘッド コストが高くなりますが、一度に多数のデータに対して実行すると、データ 1 個あたりのコストは低くなります。一度に 1 行しか作業していない場合、これらのメソッドや操作の多くは実行できません。
たとえば、データベースの結合方法を見てください。Explain Plan を見ると、結合を行ういくつかの方法がわかります。ほとんどの場合、カーソルを使用して、あるテーブルで行ごとに移動し、別のテーブルから必要な値を選択します。基本的に、これは入れ子になったループのようなものですが、ループのタイトさはありません (機械語にコンパイルされ、非常に最適化されている可能性が最も高い)。SQL Server 自体には、多数の参加方法があります。行がソートされている場合、何らかのタイプのマージ アルゴリズムが使用されます。1 つのテーブルが小さい場合は、1 つのテーブルがハッシュ ルックアップ テーブルに変換され、1 つのテーブルからルックアップ テーブルへの O(1) ルックアップを実行することによって結合が行われます。多くの DBMS には、カーソル内の 1 つのテーブルから値を検索するのに勝る多数の結合戦略があります。
ハッシュ ルックアップ テーブルを作成する例を見てください。長さ n と長さ m の 2 つのテーブルを結合する場合、テーブルを構築するにはおそらく m 回の操作が必要です。m は小さい方のテーブルです。各ルックアップは一定時間である必要があるため、n 回の操作になります。したがって、基本的にハッシュ結合の効率は m (セットアップ) + n (ルックアップ) 程度です。自分でそれを行い、ルックアップ/インデックスがないと仮定すると、n 行のそれぞれについて、m レコードを検索する必要があります (平均で m/2 検索に相当します)。したがって、基本的に操作のレベルは m + n (多数のレコードを一度に結合する) から m * n / 2 (カーソルを介してルックアップを行う) になります。また、操作も簡素化されています。カーソルのタイプによっては、カーソルの各行をフェッチすることは、最初のテーブルから別の選択を行うことと同じ場合があります。
ロックもあなたを殺します。テーブルにカーソルがある場合、行をロックしています (SQL サーバーでは、これは static および forward_only カーソルではそれほど深刻ではありません...しかし、私が目にするカーソル コードの大部分は、これらのオプションを指定せずにカーソルを開くだけです)。セットで操作を行う場合、行は引き続きロックされますが、時間は短くなります。また、オプティマイザーはユーザーが行っていることを確認でき、一連の行やページではなく、テーブル全体をロックする方が効率的であると判断する場合があります。しかし、行ごとに行けば、オプティマイザはわかりません。
もう1つのことは、Oracleの場合、カーソル操作を実行するために非常に最適化されているため、Oracleのセットベースの操作とカーソルのペナルティは、SQL Serverの場合と同じではないということです。私は Oracle の専門家ではないので、はっきりとは言えません。しかし、複数の Oracle 担当者から、Oracle ではカーソルの方がはるかに効率的であると言われました。したがって、オラクルのために長男を犠牲にした場合、カーソルについて心配する必要はないかもしれません。地元の高給のオラクルDBAに相談してください:)