7

JVM からの JMX データを多くのサーバーに約 90 日間保存することを考えています。このデータは、ヒープ サイズやスレッド数などの統計になります。これは、テーブルの 1 つに約 3 億 8800 万のレコードがあることを意味します。

このデータから、Mbean から取得した統計を比較できるようにいくつかのグラフを作成しています。これは、タイムスタンプを使用して一定間隔でデータを取得することを意味します。

したがって、本当の問題は、これらのクエリを妥当な時間内に実行できるように、テーブルまたはクエリを最適化する方法はありますか?

ありがとう、

ジョシュ

4

6 に答える 6

9

できることはいくつかあります。

  1. 実行中のクエリに一致するようにインデックスを作成します。EXPLAINを実行して、実行されるクエリの種類を確認し、可能であればすべてのクエリがインデックスを使用していることを確認します。

  2. テーブルを分割します。パーティショニングは、特定の (集約) キーによって大きなテーブルを複数の小さなテーブルに分割する手法です。MySQLはバージョンからこれを内部的にサポートします。5.1 .

  3. 必要に応じて、クエリのコストの高い部分をキャッシュするサマリー テーブルを作成します。次に、サマリー テーブルに対してクエリを実行します。同様に、メモリ内の一時テーブルを使用して、テーブルの簡略化されたビューを前処理段階として格納できます。

于 2009-01-14T18:34:13.940 に答える
2

3 つの提案:

  1. 索引
  2. 索引
  3. 索引

ps タイムスタンプについては、パフォーマンスの問題が発生する可能性があります。MySQL が DATETIME と TIMESTAMP を内部で処理する方法によっては、タイムスタンプを整数として保存する方がよい場合があります。(1970 年以降の # 秒など)

于 2009-01-14T18:29:08.223 に答える
2

まず、生データをオンデマンドでクエリするのではなく、「オフライン」処理を使用して「グラフ対応」データを生成することをお勧めします (ほとんどの一般的なケースで)。

于 2009-01-14T18:29:36.787 に答える
1

MYSQL 5.1 を使用している場合は、新しい機能を使用できます。ただし、多くのバグが含まれていることに注意してください。

まず、インデックスを使用する必要があります。これで十分でない場合は、パーティショニングを使用してテーブルを分割してみてください。

これでもうまくいかない場合は、負荷分散を試すこともできます。

于 2009-01-14T18:36:18.350 に答える
1

いくつかの提案。

おそらく、このようなものに対して集計クエリを実行するので、データをテーブルにロードした後 (またはロードしている間) に、データを事前に集計する必要があります。たとえば、時間ごと、ユーザーごと、またはアイデアを思いつき、それをレポート グラフに使用するキャッシュ テーブルに保存します。データセットを桁違いに縮小できる場合は、それで問題ありません。

これは、タイムスタンプを使用して一定間隔でデータを取得することを意味します。

これは、過去 X 日間のデータのみを使用することを意味しますか?

数千万行を削除する必要がある場合、テーブルから古いデータを削除するのは非常に遅くなる可能性があります。パーティション化はそのために最適です (古いパーティションを削除するだけです)。また、同じ期間のすべてのレコードをディスク上で近くにグループ化するため、キャッシュ効率が大幅に向上します。

MySQL を使用している場合は、MyISAM テーブルを使用することを強くお勧めします。クラッシュ耐性やトランザクションは得られず、ロックはばかげていますが、テーブルのサイズは InnoDB よりもはるかに小さいため、RAM に収まり、アクセスがはるかに高速になります。

大きなアグリゲートには多くのかなりシーケンシャルなディスク IO が含まれる可能性があるため、RAID10 (または SSD) のような高速 IO システムがプラスになります。

合理的な時間内にこれらのクエリを実行できるように、テーブルまたはクエリを最適化する方法はありますか?

それはテーブルとクエリに依存します。詳しくわからないとアドバイスできません。

大きな集計と結合を使用した複雑なレポート クエリが必要な場合、MySQL は派手な JOIN やハッシュ集計、またはその他の有用なものをサポートしていないことを思い出してください。キャッシュされたテーブルであり、ランダムアクセスが関係している場合、他のケースでは絶対にひどいものです。

Postgres でテストすることをお勧めします。大きな集計の場合、よりスマートなオプティマイザーがうまく機能します。

例 :

CREATE TABLE t (id INTEGER PRIMARY KEY AUTO_INCREMENT, category INT NOT NULL, counter INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t (category, counter) SELECT n%10, n&255 FROM serie;

(セリエには、n = 1 .. 16000000 の 16M 行が含まれます)

MySQL    Postgres     
58 s     100s       INSERT
75s      51s        CREATE INDEX on (category,id) (useless)
9.3s     5s         SELECT category, sum(counter) FROM t GROUP BY category;
1.7s     0.5s       SELECT category, sum(counter) FROM t WHERE id>15000000 GROUP BY category;

この pg のような単純なクエリでは、約 2 ~ 3 倍高速です (複雑な結合が含まれている場合、その差はさらに大きくなります)。

于 2011-04-30T10:16:09.627 に答える