我们在 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.25 亿行,并且它以每天 80 万的速度增长,这使得插入需要大约 2 个小时才能完成。插入是通过从 3 个其他表中选择数据的 3 个查询进行的。这次我们能做些什么来改善?我们应该放弃mysql并尝试其他数据库解决方案吗?
LE:根据您的反馈,我正在尝试提供更多信息。首先,这些表是 MyISAM,这些插入每晚在 cron 作业中发生一次,我们不会从中删除任何数据。这是我处理插入的方法。我将把大表称为 big_table 并且 3 个表中的每一个都将是 content_table,因为它们的结构相似。解释将是 3 张桌子中最大的一张,大约有 1.085 亿张桌子。首先我得到我应该开始使用 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 的内存,但我对存储一无所知(我一有这些信息就会回来)。并且数据不用于记录,我们只需要统计哪些用户在页面上最活跃,各种分组等,用户可以为这些指定任何时间间隔。