我需要修复缺少主键的问题,我想得到一些想法 最好的方法。
我们在几个生产数据库上有一个程序,我们每次都插入新数据 小时到总表。五列是关键,其他列是 值是不同的总和。我们使用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分钟左右。 我希望创建实际主键的时间比管理时要短 首先合并一些行。也许为少数人创建一个索引会更快 首先是键列,所以我有一个索引用于聚合行操作?
我不确定聚合行的最佳方法是什么。好不好 建议将不胜感激。
答案 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是分配的,像你想做的那样的操作应该花费我认为的时间。
希望这有帮助
干杯