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