0

Web ページで使用する SQL クエリの結果をページ分割しようとしています。言語とデータベース バックエンドは PHP と SQLite です。

私が使用しているコードは次のように機能します(ページ番号は0から始まります)

http://example.com/table?page=0

page = request(page)
per = 10 // results per page
offset = page * per

// take one extra record so we know if a next link is needed
resultset = query(select columns from table where conditions limit offset, per + 1)

if(page > 0) show a previous link
if(count(resultset) > per) show a next link

unset(resultset[per])

display results

これよりもページネーションを行う効率的な方法はありますか?

現在の方法で見られる問題の 1 つは、表示を開始する前に、10 個すべて (または多数) の結果をメモリに格納する必要があることです。これを行うのは、PDO が行数が使用可能になることを保証しないためです。

COUNT(*)クエリを発行して存在する行数を確認し、結果をブラウザにストリーミングする方が効率的ですか?

これは、「テーブルのサイズと、count(*)クエリがデータベース バックエンドで完全なテーブル スキャンを必要とするかどうかによって異なります」、「自分でプロファイリングを行う」ような質問の 1 つですか?

4

4 に答える 4

2

私は COUNT(*) の 2 つのクエリ メソッドを使用することにしました。他のメソッドでは許可されない最後のページへの直接リンクを作成できるからです。最初にカウントを実行すると、結果をストリーミングすることもできるため、少ないメモリでより多くのレコードでうまく機能するはずです。

ページ間の一貫性は私にとって問題ではありません。ご協力ありがとうございました。

于 2008-09-10T04:30:53.947 に答える
2

かなり複雑な (9-12 テーブル結合) クエリがあり、何千もの行を返し、ページ分割する必要がある場合がいくつかあります。明らかにページネーションを適切に行うには、結果の合計サイズを知る必要があります。MySQL データベースでは、SELECT で SQL_CALC_FOUND_ROWS ディレクティブを使用すると、これを簡単に実現できます。

ただし、SQLite を使用しているため、2 クエリ アプローチを使用することをお勧めします。これは、この問題に関する非常に簡潔なスレッドです。

于 2008-09-15T13:37:23.763 に答える
1

最初にカウントを行うことをお勧めします。カウント (主キー) は非常に効率的なクエリです。

于 2008-09-09T19:50:59.437 に答える
1

バックエンドが 10 行を返すのを待つことがユーザーにとって問題になるとは思えません。(画像のサイズをうまく指定したり、可能な場合はウェブサーバーに圧縮データ転送をネゴシエートさせたりすることで、それらを補うことができます。)

最初に count(*) を実行することはあまり役に立たないと思います。

複雑なコーディングをしている場合: ユーザーがページ x を見ているときに、ajax のような魔法を使用してページ x+1 をプリロードし、ユーザー エクスペリエンスを向上させます。

ページネーションに関する一般的な注意事項: ユーザーがページをブラウズしている間にデータが変更された場合、ソリューションが非常に高いレベルの一貫性を必要とする場合、問題になる可能性があります。私はそれについて別の場所にメモを書きました。

于 2008-09-09T19:52:10.683 に答える