聚合行并创建主键

时间:2012-08-08 12:16:03

标签: mysql myisam

我需要修复缺少主键的问题,我想得到一些想法 最好的方法。

我们在几个生产数据库上有一个程序,我们每次都插入新数据 小时到总表。五列是关键,其他列是 值是不同的总和。我们使用ON DUPLICATE KEY UPDATE添加到 每个插入的总和。 insert语句如下所示:

INSERT INTO sums (key1,key2,key3,key4,key5,sum1,sum2) VALUES (..., 13, 42, 3)
ON DUPLICATE KEY UPDATE sum1=VALUES(sum1)+sum1,sum2=VALUES(sum2)+sum2

事情就是在创建表时没有设置主键(不是我的错:)。 现在我需要聚合具有相同键的行,然后添加 首要的关键。由于缺少主键,表格已经增长到了周围 在一些系统上有700,000,000行,所以我需要一些有效的方法来实现这一点。

我想这样做而不必推迟每次添加新行 小时。因为在系统工作的方式现在保存插入和做 他们以后需要做很多工作。

我做的每一项操作都无法锁定表格超过45分钟左右。 我希望创建实际主键的时间比管理时要短 首先合并一些行。也许为少数人创建一个索引会更快 首先是键列,所以我有一个索引用于聚合行操作?

我不确定聚合行的最佳方法是什么。好不好 建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

首先,将现有的sums表重命名为sums_old并创建新的正确sums表,这样您就可以保持每小时的进程。但是要意识到,在应用聚合数据之前,sums表中的数据将不正确。

现在,应用以下查询来更新表:

INSERT INTO sums (key1, key2, key3, key4, key5, sum1, sum2)
SELECT key1, key2, key3, key4, key5, sum1, sum2 FROM sums_old
ON DUPLICATE KEY UPDATE sum1 = VALUES(sum1) + sum1, sum2 = VALUES(sum2) + sum2

但是等等,因为你正在使用MyISAM,并且你不希望表被锁定太长时间,所以使用LIMIT进行分块:

INSERT INTO sums (key1, key2, key3, key4, key5, sum1, sum2)
SELECT key1, key2, key3, key4, key5, sum1, sum2 FROM sums_old
ORDER BY some_index
LIMIT 0, 250000
ON DUPLICATE KEY UPDATE sum1 = VALUES(sum1) + sum1, sum2 = VALUES(sum2) + sum2

INSERT INTO sums (key1, key2, key3, key4, key5, sum1, sum2)
SELECT key1, key2, key3, key4, key5, sum1, sum2 FROM sums_old
ORDER BY some_index
LIMIT 250000, 250000
ON DUPLICATE KEY UPDATE sum1 = VALUES(sum1) + sum1, sum2 = VALUES(sum2) + sum2

INSERT INTO sums (key1, key2, key3, key4, key5, sum1, sum2)
SELECT key1, key2, key3, key4, key5, sum1, sum2 FROM sums_old
ORDER BY some_index
LIMIT 500000, 250000
ON DUPLICATE KEY UPDATE sum1 = VALUES(sum1) + sum1, sum2 = VALUES(sum2) + sum2

...

你需要通过一些键来按顺序排序,所以如果你没有,你需要将它添加到sums_old表中。

找出一个好的块大小。

答案 1 :(得分:0)

我会说尝试这样的东西来聚集它们

select key1,key2,key3,k4,key5,
convert(key1 as varchar) + convert(key2 as varchar) + convert(key3 as varchar) + convert(k4 as varchar) + convert(key5 as varchar) as Pk
from sums
group by key1,key2,key3,k4,key5
having distinct(convert(key1 as varchar) + convert(key2 as varchar) + convert(key3 as varchar) + convert(k4 as varchar) + convert(key5 as varchar))

我不羡慕你,700M是分配的,像你想做的那样的操作应该花费我认为的时间。

希望这有帮助

干杯