2012-08-08 62 views
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分钟左右。 我希望创建实际主键的时间要短于如果我管理 先合并某些行。也许这是更快的创建一个索引 键列首先,所以我有一个索引用于聚合行操作?

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

+2

按键1到5的任何一个按时间顺序排列?这样您可以识别在某个时间点之后添加的行吗?在这种情况下,我会以块的形式运行聚合查询 - 首先是第一百万行,然后是第二行等 - 然后将聚合结果复制到新表中。这可能足够快,以便您不要将表格锁定时间过长,并且您可以在不到45分钟的时间内切换到最后一次运行后的新表格。 – 2012-08-08 12:39:24

+0

是的,其中一个关键列是基于日期的。我想对于实际的合并,我需要通过大块来完成。也许最好的开始方式是为基于日期的列添加索引,并查看需要多长时间。我猜想建立一个索引的速度比同时使用所有键的索引要快一些。 – ygram 2012-08-08 12:44:59

回答

1

首先,重命名现有的资金表sums_old并创建新的,正确的资金表,所以你可以保持您小时的过程去。但是,要意识到,除非您应用汇总数据,否则汇总表中的数据将不正确。

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

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表。

找出一个好的块大小是多少。

+0

要创建一个新表并让小时过程插入该表中,这是一个非常好的主意。我只需要说服一些客户说,获取不正确数据一段时间比获取数据要好(因为每个查询都是全表扫描,所以现在发生了什么)。 – ygram 2012-08-08 14:07:28

0

我要说尝试这样的东西agregate他们

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的配发,操作就像你想做的事应该采取配发的时候,我觉得一个。

希望这有助于

干杯