いくつかの提案。
おそらく、このようなものに対して集計クエリを実行するので、データをテーブルにロードした後 (またはロードしている間) に、データを事前に集計する必要があります。たとえば、時間ごと、ユーザーごと、またはアイデアを思いつき、それをレポート グラフに使用するキャッシュ テーブルに保存します。データセットを桁違いに縮小できる場合は、それで問題ありません。
これは、タイムスタンプを使用して一定間隔でデータを取得することを意味します。
これは、過去 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 倍高速です (複雑な結合が含まれている場合、その差はさらに大きくなります)。