2011-01-05 10 views
1

ページングされた結果を処理する際のアイテムの合計数を追跡する理想的な方法は何ですか?一連のページングされた結果の合計数を追跡する

これは最初は簡単な質問のようですが、実際に効率的に行う方法を考え始めると、ちょっと複雑になりました。

データベースからアイテム数を取得する必要があります。これは簡単です。私はいくつかの変数(例えば、$ _SESSION変数)にこの数を格納することができます。私はこの変数が設定されているかどうかを調べることができます。そうでない場合は、カウントを再度取得します。私が新しいカウントを取得する必要があるときを判断する最良の方法は何ですか?アイテムを追加/削除した場合、またはグリッドをリロードしたり再訪している場合は、新しいカウントを取得する必要があるようです。

したがって、この$ _SESSION変数をいつ削除するのかを決めるにはどうすればよいですか?私はそれをクリアし、更新/削除後に新しいカウントを得ることができます(あるいは、高価なデータベースのヒットを避けるために追加または削除することもできます)。(ここでは難しい部分があります)または結果の次のページに行く前に可変量の時間待つか、ページをリロードしますか?

私たちは数十万の結果を扱っている可能性があるので、データベースからそれらの数を得ることはかなり高価になる可能性があります(正しくは私の仮定は間違っていますか?)。ページングされた結果の総ページ数を処理するために合計カウントが必要なので...必要な場合に限り、このような状況を処理し、それを維持する最も効率的な方法は何ですか?

SELECT COUNT(id) FROM foo; 
+1

多くの結果では、丸められた数字を使用して、約22Kの結果やそのようなものを言いたいことがあります。 – dqhendricks

答えて

3

私は情報を取得し、カウント自体は2番目のクエリから来るとき、私は定期的なクエリのカウントが含まれ、クエリで見つかった合計を保存するためにセッション変数を使用することはありません:

// first query 
SELECT SQL_CALC_FOUND_ROWS * FROM table LIMIT 0, 20; 
// I don´t actually use * but just select the columns I need... 

// second query 
SELECT FOUND_ROWS(); 

I 2番目のクエリのためにパフォーマンス低下に気づいたことはありませんでしたが、確かめたい場合は、それを測定する必要があります。

ところで、私はこれをPDOで使用しています。私は単純なMySQLで試したことがありません。

+0

@Scuzzy代わりに 'LIMIT'節の後に*行数を返すと思います前の – jeroen

+0

ああ私の間違いです、私のコメントは間違っています、私はそれを削除しました。 – Scuzzy

1

なぜそれがセッション変数に格納します。

ところで、私のようなSQLクエリでのカウントになるだろうか?結果はユーザーごとに変更されますか?私はむしろ、APCやmemcachedのようなユーザーのキャッシュに保存し、キャッシュキーを賢明に選択してから、クエリに関連するレコードを挿入または削除するときにクリアします。

Doctrineのように、あなたのために行うORMを使用することをお勧めします。これはresult cacheです。

カウントを取得するには、COUNT(*)を使用するのがCOUNT(ID)を使用するよりも悪くないことがわかります。 (質問:?それはさらに良いです)

EDIT:the MySQL performance blog

+0

"なぜセッション変数に格納するのですか?"唯一の理由は、結果のページ間を移動するのに費やされた時間に再利用できるということでした。 APC、memcachedおよび/またはDoctrineが利用できないと仮定して、他に提案がありますか?それらは有益な提案です...これを達成するための最も裸の骨の方法を探しているだけです。 – Lothar

+0

キャッシュシステムでは、キャッシュはページとユーザー間で持続するため、大きなメリットがあります。推奨されているクールなツールのいずれも利用できない場合は、次のような独自のキャッシュシステムを構築することができます。http://www.siteduzero.com/tutoriel-3-31906-comprendre-et-utiliser-un- systeme-de-cache-php.htmlしかし、これらのツールをインストールして使用する方がはるかに簡単です – greg0ire

+1

Gregはファイルベースのキャッシュについて、ユーザー固有のものではないことを言います。例:http://www.jongales.com/blog/2009/ 02/18/simple-file-based-php-cache-class /を指定すると、有効期限のあるファイルを作成し、ページが読み込まれるたびにそのデータが欠落しているかどうかを確認してから削除し、 – RobertPitt

1

にこのことについて興味深い記事ほとんどのfooid列に定義されたPRIMARY KEY率を有しています。インデックスは通常、DB上では非常に簡単です。COUNT()

しかし、あなたが余分に移動したい場合、別のオプションは、行の挿入と削除を扱うコードに特殊なフックを挿入してfooにすることです。それぞれの挿入/更新の後に保護されたファイルに総レコード数を書き込んでそこから読み込みます。成功したすべての挿入/更新が考慮されると、保護されたファイルの番号は常に最新の状態になります。

関連する問題