基本的にページでのユーザーアクションを記録するMySQLテーブルに次のデータ構造があります
id int
page_id int
user_id int
action_type enum(6)
date_created datetime`
次のインデックスがあります。
id Primary key
user_id-page_id-date_created unique
page_id-user_id-date_created
user_id
page_id-date_created
問題は、このテーブルには現在 1 億 2500 万行あり、1 日あたり 80 万行の割合で増加しているため、挿入が完了するまでに約 2 時間かかることです。挿入は、他の 3 つのテーブルからデータを選択する 3 つのクエリによって行われます。今回は何を改善できるでしょうか?mysql をやめて、他のデータベース ソリューションを試す必要がありますか?
LE:あなたのフィードバックに基づいて、私はより多くの情報を提供しようとしています. まず、テーブルは MyISAM であり、これらの挿入は cron ジョブで毎晩 1 回行われ、テーブルからデータを削除することはありません。これが私がインサートを処理する方法です。大きなテーブルを big_table と呼び、3 つのテーブルはそれぞれ構造が似ているので content_table とします。説明は、約 1 億 850 万の 3 つのテーブルのうち最大のものになります。最初に、php を使用して挿入を開始する ID を取得します。(インデックスなしのクエリが取得するのに3分かかります)
SELECT id FROM content_table WHERE date_created > "2012-04-18" ORDER BY id ASC LIMIT 1;
+-----------+
| id |
+-----------+
| 107278872 |
+-----------+
1 row in set (3 min 15.52 sec)
EXPLAIN SELECT id FROM content_table WHERE date_created > "2012-04-18" ORDER BY id ASC LIMIT 1;
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | content_table | index | NULL | PRIMARY | 4 | NULL | 1 | Using where |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.06 sec)
そして、このIDを使用して、次のことを行います
INSERT IGNORE INTO big_table (user_id, page_id, type, date_created)
SELECT user_id, page_id, IF (is_admin,"admin_action","action") as type, created_time FROM content_table WHERE id >= "107278872";
選択の説明は次のようになります
EXPLAIN SELECT user_id, page_id, IF (is_admin,"admin_action","action") as type, created_time FROM content_table WHERE id >= "107278872";
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+
| 1 | SIMPLE | content_table | range | PRIMARY | PRIMARY | 4 | NULL | 777864 | Using where |
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+
1 row in set (0.00 sec)
私もphpmyadminで試してみたところ、約0.004秒の時間が得られたので、データのフェッチではなく挿入に時間がかかると思います。サーバーについて私が知っているのは、それがクアッドコア xeon @ 2.4 ghz と 16 GB の RAM であることだけですが、ストレージについては何も知りません (その情報が得られたらすぐに戻ってきます)。また、データはロギングには使用されませんが、どのユーザーがページで最もアクティブであったか、さまざまなグループ化などの統計が必要であり、ユーザーはこれらの間隔を指定できます。