テーブルには主キーがあります。それを利用してください。
LIMITの代わりに およびOFFSET 、主キーのフィルターを使用してページングを実行します。あなたはコメントでこれをほのめかしました:
ランダムな数値を使用したページング(各クエリに「GREATERTHAN ORDER BY」を追加)
しかし、それをどのように行うべきかについてランダムなことは何もありません。
SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2
クライアントが両方のパラメーター、最後に見たID、およびフェッチするレコードの数を指定できるようにします。 APIには、プレースホルダー、追加のパラメーター、または「最初のをフェッチする」ための代替呼び出しのいずれかが必要です。 WHEREを省略した「nIDs」 クエリからの句ですが、それは些細なことです。
このアプローチでは、かなり効率的なインデックススキャンを使用してレコードを順番に取得し、通常、スキップされたすべてのレコードの並べ替えや反復の必要性を回避します。クライアントは、一度に必要な行数を決定できます。
このアプローチは、LIMITとは異なります。 およびOFFSET 1つの重要な方法でのアプローチ:同時変更。 INSERTの場合 下のキーを使用してテーブルに移動します OFFSETに対して、一部のクライアントがすでに見たキーよりも、このアプローチは結果をまったく変更しません。 アプローチは行を繰り返します。同様に、DELETEの場合 OFFSETに対して、このアプローチの結果は、すでに表示されているIDよりも低いIDの行は変更されません。 見えない行をスキップします。ただし、生成されたキーを持つ追加専用テーブルには違いはありません。
クライアントが結果セット全体を必要とすることが事前にわかっている場合、最も効率的な方法は、このページングビジネスを一切使用せずに結果セット全体をクライアントに送信することです。それが私がする場所です カーソルを使用します。 DBから行を読み取り、クライアントが受け入れるのと同じ速さでそれらをクライアントに送信します。このAPIは、過度のバックエンドの負荷を回避するために、クライアントが許可される速度に制限を設定する必要があります。遅いクライアントの場合は、おそらくページングに切り替えるか(上記のように)、カーソルの結果全体を一時ファイルにスプールしてDB接続を閉じます。
重要な注意事項 :
-
UNIQUEが必要です 制約/UNIQUEインデックスまたはPRIMARY KEY信頼できること - 制限/オフセットするためのさまざまな同時変更動作。上記を参照