2

我需要解决缺少主键的问题,并且我想就最佳方法获得一些想法。

我们在几个生产数据库上有一个程序,我们每小时将新数据插入总和表。其中五列是键,其他列是不同总和的值。我们使用 ON DUPLICATE KEY UPDATE 在每次插入时添加总和。插入语句看起来像这样:

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 分钟左右。如果我设法先合并一些行,我希望创建实际的主键将花费更短的时间。也许首先为一些键列创建索引会更快,所以我有一个用于聚合行操作的索引?

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

4

2 回答 2

1

首先,将您现有的 sums 表重命名为 sums_old 并创建新的正确 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 表中。

弄清楚什么是好的块大小。

于 2012-08-08T13:48:33.637 回答
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是分配的,我想像你想做的那样的操作应该需要分配的时间。

希望这可以帮助

干杯

于 2012-08-08T12:32:54.393 回答