我们在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并尝试其他数据库解决方案吗?
L.E:根据您的反馈,我想提供更多信息。 首先,这些表是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.004s的时间,所以我认为这是插入需要时间而不是数据获取。我所知道的服务器是它是一个四核xeon @ 2.4 ghz和16 GB的ram,但我对存储一无所知(只要我有这个信息就会回来)。并且数据不仅用于日志记录,我们需要具有哪些用户在页面上最活跃的统计数据,各种分组等,并且用户可以为这些设置指定任何间隔。
答案 0 :(得分:3)
你可以:
所有关系数据库都将不得不处理太多数据。你的第一个想法不应该是放弃MySQL;它应该弄清楚你的归档策略需要什么。您必须确定在给定时间内事务存储中需要多少数据。
答案 1 :(得分:0)
影响插入的因素很多,例如
首先告诉我们你是如何插入数据的,第二件事是存储引擎用于表,然后我们可以进一步优化你插入查询,一般来说我可以说不必要的索引意味着插入速度慢。
的更多说明答案 2 :(得分:0)
你是如何插入它们的?您每秒只能有一定数量的事务循环查询,如此
//start loop
insert into table values (1)
//end loop
比
慢很多//start loop
//fill a variable
//end loop
insert into table values (1),(2),(3),(4) // where (1),(2),(3),(4) are values filled by the loop
(请注意,您不能插入太多像这样的值,尝试使用您的数据,我通常会发现200左右的值非常好)
你没有大量的索引,所以我不认为它们会引发问题,phpmyadmin显示索引大小,检查与总表大小相比的内容 - 这可能会让你知道它是否存储过多< / p>