我们正在使用MySQL。 我们有一个非常长的表(110m * 7),我们经常在这个表中添加新记录(当这样做时,我们上传csv文件,所以从来不会是一个非常痛苦的过程甚至大量的记录)。
现在我们需要在此表中添加一个新列,以某种方式区分记录。具体而言,最近添加的约1000万条记录将被标记为类型2,所有旧记录将被标记为类型1.并且将来,我们将为这两种类型添加新记录。
首先,我们尝试了如下方法1,但它运行了超过24小时而没有任何抱怨,主机服务器始终响应。
-- ====================================================
-- start of approach 1
-- ====================================================
-- Add column.
ALTER TABLE
bond_price
ADD
bp_name_version SMALLINT
;
-- Set value 1 for BOND_CHARACTER types.
UPDATE
bond_price
SET
bp_name_version = 1
WHERE
bp_serial_id < 107480325
;
-- Set value 2 for BOND_CHARACTER_EIKON types.
UPDATE
bond_price
SET
bp_name_version = 2
WHERE
bp_serial_id >= 107480325
;
-- Set a NOT NULL constrain on the new column
ALTER TABLE
bond_price
ALTER
bp_name_version SET NOT NULL
;
-- ====================================================
-- END of approach 1
-- ====================================================
我们在24小时后失去了信仰,认为设定条件条款可能会让这么长的桌子变得困难。所以我们尝试了方法2,即逐步进行方法1,没有条件子句。
所以我们首先执行以下查询,并在几秒钟内完成。
-- Add column.
ALTER TABLE
bond_price
ADD
bp_name_version SMALLINT
;
然后我们执行以下查询将值1放到所有记录中,希望稍后我们可以将只有1000万条记录的值更改为2。
-- Set value 1 for all records.
UPDATE
bond_price
SET
bp_name_version = 1;
但是这个查询已经运行了24个小时到现在,再次没有抱怨任何事情。
我们一直在监控服务器:
select * from pg_stat_activity;
“设置值1”查询仍处于活动状态,服务器仍然非常敏感。
我们的问题:
非常感谢提前!
答案 0 :(得分:1)
我不知道这些数据的基础,但一次推出的记录超过了一万两千万。
为什么不尝试找到其他一些标准,做一个循环,然后在较小的块中进行...可能基于一些“添加”日期或结构中的其他一些字段。或者,只使用bp_serial_id,例如(再次由循环处理)
一次最多更新100万的伪代码
maxSerialForType1 = 107480325
for cycle = 0 to 110
startSerialID = cycle * 1000000
endSerialID = (cycle +1 ) * 1000000
if startSerialID < maxSerialForType1
UPDATE bond_price
SET bp_name_version = 1
WHERE bp_serial_id < maxSerialForType1
AND bp_serial_id >= startSerialID
AND bp_serial_id < endSerialID
end for update type 1
if startSerialID > maxSerialForType1
UPDATE bond_price
SET bp_name_version = 2
WHERE bp_serial_id > maxSerialForType1
AND bp_serial_id >= startSerialID
AND bp_serial_id < endSerialID
end for update type 2
end of loop
所以这个,如果像存储过程一样,将为你更新1.1亿。
然后我会建议,当将新记录导入到临时表中并在其中分配bp_name_version值时,然后将它们拉入最终表,这样您就不必每次都尝试更新超过110万