MySQLデータベースで「selectsum(foo)from bar」クエリを実行しています。これは、7.3mmレコードを合計し、実行ごとに約22秒かかります。 MySQLで合計を高速化するコツはありますか?
いいえ、関数自体を高速化することはできません。ここでの問題は、実際には730万レコードを選択していることです。 MySQLはテーブル全体をスキャンする必要があり、730万はかなり大きな数です。実はこんなに早く終わってしまったのが印象的です。
採用できる戦略は、データをより小さなサブセットに分割し(おそらく日付ごと、月ごと?)、変更されない古いデータの合計を維持することです。合計を定期的に更新することができ、合計と、それ以降に追加された新しいデータを追加することで全体の値を計算できます。これにより、行数が大幅に少なくなります。
MysqlでQUERYCACHEをオンにします。キャッシュはデフォルトでオフになっています。 mysqliniファイルを設定する必要があります。
-- hint mysql server about caching
SELECT SQL_CACHE sum(foo) FROM bar;
テーブルに変更が加えられていない場合、MySQLオプティマイザはキャッシュを返すことができる場合があります。
詳細はこちら: http://www.mysqlperformanceblog.com/2006/07/27/mysql-query-cache/
ここで2つのこと:
1)定期的に730万レコードの合計を行うべきではありません-ビジネスニーズ(日、月、年、部門など)に対応するステージングテーブルを導入し、スケジュールに基づいて入力します。元のテーブルの代わりにそれらのテーブルを再利用する可能性があります。 'テーブル(数日間隔が必要な場合の各日の要約値の選択など)
2)トランザクション設定を確認します
http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read
いいえ、そうではありません。テーブル内のすべての行を常に列挙する必要があります。
追加のテーブルを作成し、挿入、更新、削除のたびにその合計を更新できますか?
おそらくbar.fooフィールドにインデックスを追加してみることができます。インデックスにはbar列のすべての値が含まれますが、特にfooに他の列が多数ある場合は、元のfooテーブルよりも小さいためスキャンが高速になります。
クエリが本当に単純な場合は、違います...しかし、より複雑なクエリを使用している場合(ここでは省略している場合)、(おそらく)-より良い結合を使用するように...