2011-07-24 14 views
2

テーブル用の統計情報を作成しようとしましたが、3百万行以上の行があるため、実際には遅いです。GROUP BYとORDER BYが遅すぎます。もっと速くするには?

私は列nameの最も一般的な値を見つけようとしています。また、何回ポップアップしたかを示しています。

私はmommentでこれを使用していますが、動作が遅すぎるため、エラーが発生します。

$total = mysql_query("SELECT `name`, COUNT(*) as b FROM `people` GROUP BY `name` ORDER BY `b` DESC LIMIT 0,5;")or die(mysql_error()); 

あなたは私がすべての名前を取得しようと何回名前が使用されていることだけうまくいけば、それをスピードアップするために、トップ5を表示しています見ているよう。

私はその後、

while($row = mysql_fetch_array($result)){ 
     echo $row['name'].': '.$row['b']."\r\n"; 
    } 

のような値を得るのですかできるようにしたいと思いますそして、それはこのようなものが表示されます。

Bob: 215 
    Steve: 120 
    Sophie: 118 
    RandomGuy: 50 
    RandomGirl: 50 

私は間違った方法でラウンドして、その後RandomGirlとRandomGuyのような名前の発注についてはあまり気にしません。

私は十分な情報を提供していると思います。 :)可能であれば、名前の大文字小文字を区別しないようにしたいと思います。 BobはBoB、bOb、BOBなどと同じでなければなりません。

お礼のお時間 ポール

+3

データベースの 'name'にインデックスがありますか?それは我々が逃している重要な情報であり、最も可能性の高い最適化です... –

+1

EXPLAIN の出力とCREATE TABLEステートメントを追加してください。 – wonk0

+2

'EXPLAIN SELECT ...'を実行する習慣を身につけ、あなたの質問のテーブルのDDLと一緒にそれの出力を含めて。これは、MySQLが何をしているか、どのような改善が見られるのかをあなた(そして私たち)に伝えます。詳細はhttp://dev.mysql.com/doc/refman/5.0/en/explain.htmlを参照してください。 –

答えて

5

トップ5の結果を制限しても、検索結果に時間がかかることはありませんが、mySQL側ではテーブル全体を解析する必要があります。

インデックスの名前列を持つカウントクエリのスピードアップはもちろん、インデックスのみが解析され、テーブルは解析されないためです。

本当に結果を高速化し、この結果が必要なときに名前インデックスの解析を避けたい場合(実際に何百万行もある場合はかなり遅くなります)、唯一の他の解決策は統計を計算することですこの表の行を挿入、削除または更新するときに使用します。つまり、このテーブルのをトリガを使用してこの近くの統計テーブルを維持します。そうすれば、この統計テーブルでは単純に5つの行しか解析されない単純な選択クエリしか得られません。しかし、インサート、削除、更新操作の速度が遅くなります(インデックスが維持されている場合は非常に遅いため、統計が重要な場合はこのソリューションを検討する必要があります)。

+0

+1シャドウ値のヒント –

2

ためには、あなたが名前にインデックスを持っていますか?それは助けるかもしれない。

1

名前のインデックスをグループ化してから並べ替えると、MySqlが毎回すべての行を処理する必要があります。これを最適化する方法はありません。

CREATE TABLE name_stats(name VARCHAR(n), cnt INT, UNIQUE(name), INDEX(cnt)) 
、あなたはこのように「人のテーブルに新しい行を追加するたびに、このテーブルを更新する必要があります:あなたは、このような個別の 統計テーブルを持っている必要があります

このテーブルを照会
INSERT INTO name_stats VALUES('Bob', 1) ON DUPLICATE KEY UPDATE cnt = cnt + 1; 

トップ名のリストには、結果が瞬時に表示されます。