2011-07-12 8 views
3

メッセージアプリケーション(メールなど)を作成していて、メッセージ数を数えなければならなかった。MySQLの計算能力

メッセージを毎回カウントするほうがよいでしょうか、それともメッセージが受信されたときに新しいカラムをnumOfMsgとして増やすべきですか?

EDIT:

それは、誰もが自分の意図が何であったか知っている、phpBBのhttp://wiki.phpbb.com/Table.phpbb_topicsデータベースに格納返信番号のように思えますか?

+0

これは、メッセージテーブルの一部またはすべての行を数えているかどうかによって異なります。セカンダリキーに基づく1つのメールボックスのメッセージ?また、メッセージテーブルのサイズも重要です。もしあなたが適切な指数を持っていれば、私は100k行以下のテーブルについては心配しません。 – Martijn

答えて

1

メッセージをカウントするには、MySQL機能COUNT()を使用します。適切なインデックスを使用すると、これは非常に高速です。 (ユーザ+ボックスでカウントを行う場合は、ユーザ+ボックスにインデックスを組み合わせることをお勧めします)

新しいメッセージが到着していない限り、MySQLはクエリの結果もキャッシュしますメッセージテーブルは変更されていません]実際のカウントを行うためにメモリ/ディスクに戻ることさえありません。最後の値を返します。非常に安い操作です

余分な冗長な情報を保持することの問題は、これを最新の状態に保つのが非常に難しいことです。メッセージを追加または削除することができます。一部のユーザーはボックス間でメッセージを移動することがあります。このすべての時間は、カウンタを正しい状態に保つ必要があります。また、トランザクションの使用を開始して、メッセージのINSERTとカウンタのUPDATEの両方が実行されているか、または両方が実行されていないことを確認する必要があります(接続が失われたり、クラッシュするなど)。

1

これは良い質問です。その答えは、アプリケーションの規模によります。実行時の集計を維持することは間違いなく、必要なときにそれらの数値を取得するのを簡単に/迅速にするでしょうが、メッセージが挿入、削除、または移動されるたびに追跡する必要があるため、メールボックス/フォルダ(アプリケーションで許可されている場合)

カウントを最新の状態に保つ努力をしていれば、それはおそらくそのようなことのための良いアプローチです。

私が書いたコードでは、このような状態カウンタを使用しています。

0

numOfMsgフィールドを持つことはお勧めできません。プログラムの番号を把握しておく必要があります。とにかく、MySQL optimizes COUNT(*)と私はそれがあなたのアプリケーションのボトルネックになるのではないかと疑います。

+1

MySQLは、WHERE(つまりテーブル全体)とfo MyISAMテーブルのみが存在しない場合にのみCOUNT(*)を最適化します。 – Mchl

+0

はい、MyISAMの場合のみですが、WHEREを指定しても適切なインデックスが設定されていれば可能です。 – Jacob

1

もちろん、メッセージ数のキャッシュは高速です。しかし、適切なインデックスがあり、1人のユーザーに100万のメッセージがないと仮定すると、数え方は十分に速いです。もちろん、ストレージエンジンにも依存します(たとえば列ベースのストレージエンジンは、aggragate関数のほうが高速です)。 毎回ユーザーデータを選択していると仮定すると、同じ行にメッセージ数があると毎回1つのクエリが保存されます。

私のアドバイスは、性能に影響がない限り、カウントしています。カウントのためにパフォーマンスが低下した場合は、カウントをキャッシュします。キャッシュでさえ十分でない場合、データベースの非正規化について考えることができます。時期尚早の最適化は有用ではありません。その答えは、アプリケーションの規模や新しいメッセージの頻度に大きく依存します。