我正在寻找一种更新一个表中数十亿条记录的最佳方法(表3中的示例)。每个条目都与时间戳相关联,该时间戳的大小为毫秒级。在此示例中,表3已过期,表1和表2是最新的,其中包含各自数据的实际条目。我没有将表1和表2连接到表3的任何内容。如果需要,请告诉我,因为我不是数据库专家。
表1有4列:
Timestamp T_0 PRIMARY KEY (ex: '2014-07-04 16:17:16.800000')
X1_T1 VARCHAR
X2_T1 VARCHAR
X3_T1 VARCHAR
表2有4列:
Timestamp T_0 PRIMARY KEY (ex: '2014-07-04 16:17:16.800000')
X1_T2 VARCHAR
X2_T2 VARCHAR
X3_T3 VARCHAR
表3有7列:
Timestamp T_0 PRIMARY KEY (ex: '2014-07-04 16:17:16.800000')
X1_T1 VARCHAR
X2_T1 VARCHAR
X3_T1 VARCHAR
X1_T2 VARCHAR
X2_T2 VARCHAR
X3_T3 VARCHAR
我使用循环时间戳并使用命令更新每一行的过程成功更新了表3:
SET tmp_T_0=(SELECT '2014-01-05 17:00:00.000000'); // set to the start of the table's timestamp
label1: LOOP
UPDATE TABLE3 SET
X1_T1=(select X1_T1 FROM TABLE1 where T_0 = tmp_T_0),
X2_T1=(select X2_T1 FROM TABLE1 where T_0 = tmp_T_0),
X3_T1=(select X3_T1 FROM TABLE1 where T_0 = tmp_T_0),
X1_T2=(select X1_T2 FROM TABLE2 where T_0 = tmp_T_0),
X2_T2=(select X2_T2 FROM TABLE2 where T_0 = tmp_T_0),
X3_T2=(select X3_T2 FROM TABLE2 where T_0 = tmp_T_0)
WHERE T_0 = tmp_T_0;
SET tmp_T_0=(SELECT TIMESTAMP(tmp_T_0,'00:00:00.001')); //ADD one millisecond and continue
SET LoopInt=(SELECT(LoopInt + 1));
IF LoopInt < LoopEnd THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
对于100,000个条目,上述方法大约需要53秒。这是不可接受的,因为完成剩下的参赛作品需要大约100天。
应该注意的是,表3具有来自表1和/或2的每个时间戳条目的数据不是必须的(即,表3中的时间戳可以包含X1_T1 X2_T1的数据和X3_T1而其他值X1_T2 X2_T2和X3_T2为NULL)。
任何建议都会有所帮助。 谢谢
答案 0 :(得分:0)
尝试此查询从TABLE1到TABLE3提取一小时的信息怎么样?
UPDATE TABLE3 AS t3
JOIN TABLE1 AS t1 ON t3.T_0 = t1.T_0
SET t3.X1_T1 = IFNULL(t1.X1_T1,t3.X1_T1),
t3.X2_T1 = IFNULL(t1.X2_T1,t3.X2_T1),
t3.X3_T1 = IFNULL(t1.X3_T1,t3.X3_T1)
WHERE t3.T_0 >= '2014-01-05' + INTERVAL 0 HOUR
AND t3.T_0 < '2014-01-05' + INTERVAL 1 HOUR
发生了什么?首先,WHERE
子句将查询的范围限制为一小时。这很方便,因为你可以测试一些东西。此外,您还希望逐个小时循环播放此作业,以免您的查询运行时间过长。如果您使用InnoDB或Aria作为存储引擎,如果您不限制查询范围,那么您也会破坏事务回滚空间。
您可以多次运行此查询,每次更改HOUR间隔,就像这样。
WHERE t3.T_0 >= '2014-01-05' + INTERVAL 1 HOUR
AND t3.T_0 < '2014-01-05' + INTERVAL 2 HOUR
您正在将TABLE1加入TABLE3。这是有效的,因为您说TABLE3包含每个可能的时间戳,而TABLE1不包含。我编写此查询的方式,它不会触及TABLE3中没有TABLE1中相应行的行。我认为这就是你想要的。
最后,当有非NULL TABLE1数据时,IFNULL()函数只安排改变TABLE3数据。
看,如果你的TABLE1数据稀疏(也就是说,它在表中有很多随机分散的有效值,大多数是NULL)你可能想要使用这样的三个查询,所以你实际上并不是这样除非您有新数据,否则更改TABLE3中的行。更改行中的值相对昂贵。
UPDATE TABLE3 AS t3
JOIN TABLE1 AS t1 ON t3.T_0 = t1.T_0
SET t3.X1_T1 = t1.X1_T1
WHERE t3.T_0 >= '2014-01-05' + INTERVAL 0 HOUR
AND t3.T_0 < '2014-01-05' + INTERVAL 1 HOUR
AND t1.X1_T1 IS NOT NULL
UPDATE TABLE3 AS t3
JOIN TABLE1 AS t1 ON t3.T_0 = t1.T_0
SET t3.X2_T1 = t1.X2_T1
WHERE t3.T_0 >= '2014-01-05' + INTERVAL 0 HOUR
AND t3.T_0 < '2014-01-05' + INTERVAL 1 HOUR
AND t1.X2_T1 IS NOT NULL
UPDATE TABLE3 AS t3
JOIN TABLE1 AS t1 ON t3.T_0 = t1.T_0
SET t3.X3_T1 = t1.X3_T1
WHERE t3.T_0 >= '2014-01-05' + INTERVAL 0 HOUR
AND t3.T_0 < '2014-01-05' + INTERVAL 1 HOUR
AND t1.X3_T1 IS NOT NULL
您需要为TABLE2数据重复所有这些。
您可能希望在单个查询中运行此全部内容。别这么做!这是您需要能够一次完成一小时并在需要时重新启动的工作。我建议一次一个小时,但这是3.6个megarows。你可能想要一次做更小的块,比如6分钟(360千里)。
如果我是你,我肯定会在几天的时间内调试整个交易。&#39;值得你的TABLE3。