カーソルは、大規模なデータ セットを処理する小規模なイントラネット アプリケーションのページングに適した選択肢ですが、タイムアウト後に破棄できるようにしておく必要があります。ユーザーは、うろうろしたり、ランチに行ったり、2 週間の休暇に出かけたりすることを好み、アプリケーションを実行したままにします。Web ベースのアプリの場合、「実行中」とは何か、ユーザーがまだ存在しているかどうかをどのように確認するかという問題さえあります。
Web ベースのアプリや Web API のように、クライアント数が多く、クライアントがほぼランダムに出入りする大規模なアプリケーションには適していません。クライアント数がかなり少なく、要求レートが非常に高い場合を除き、アプリケーションでカーソルを使用することはお勧めしません...その場合、行の小さなバッチを送信することは非常に非効率的であり、代わりに範囲要求などを許可することを検討する必要があります.
カーソルにはいくつかのコストがあります。カーソルがないWITH HOLD
場合は、トランザクションを開いたままにしておく必要があります。トランザクションが開いていると、自動バキュームが適切に機能しなくなり、テーブルの肥大化やその他の問題が発生する可能性があります。カーソルが宣言さWITH HOLD
れ、トランザクションが開いたままにされていない場合、潜在的に大きな結果セットを具体化して保存するコストを支払う必要があります-少なくとも、それがホールドカーソルの仕組みだと思います。代わりに、カーソルが破棄されるまでトランザクションを暗黙的に開いたままにし、行のクリーンアップを妨げます。
さらに、カーソルを使用している場合、接続を接続プールに戻すことはできません。クライアントごとに 1 つの接続が必要です。これは、セッション状態を維持するためにより多くのバックエンド リソースが使用されることを意味し、カーソルベースのアプローチで処理できるクライアント数に非常に実質的な上限を設定します。
また、制限とオフセットを使用したステートレスな接続プーリング アプローチと比較して、ステートフルなカーソル ベースのセットアップを管理する複雑さとオーバーヘッドもあります。タイムアウト後にアプリケーションのカーソルを期限切れにする必要があります。そうしないと、サーバー上で無限にリソースが使用される可能性があり、どの接続がどのユーザーに対してどの結果セットに対してどのカーソルを持っているかを追跡する必要があります....
一般に、それは非常に非効率的であるという事実にもかかわらず、より良い解決策になる可能性がLIMIT
あります. ただし、を使用するよりも主キーを検索する方がよい場合がよくあります。OFFSET
OFFSET
ところで、あなたは PL/pgSQL のカーソルのドキュメントを見ていました。このジョブには通常の SQL レベルのカーソルが必要です。
カーソルでは、データベース接続を開いたままにする必要がありますか?
はい。
カーソルはトランザクション内で実行され、「クローズ」されるまでリソースをロックしますか?
WITH HOLD
他のデータベース リソースを消費する場合を除き、はい。
私が気付いていない他の「落とし穴」はありますか?
はい、上記のとおりです。