trim 一列大数据的最快方法 MySQL table

Fastest way to trim one column's data in large MySQL table

我继承了一个有很多问题的数据库。我目前正在尝试解决的问题之一是许多 table 具有字符主键,这些主键用空格填充到 10 个字符。

在大多数情况下,我已经能够相当轻松地更新 table 以删除填充。但是,有一个辅助table,它有超过一千万条记录。它有一个 table 之一的外键,带有填充的主键。

我想将这个外键列的所有值更新为它们的修剪值。我尝试了一个简单的更新查询。

UPDATE actions SET foreignkey = TRIM(foreignkey);

这给了我错误 "The total number of locks exceeds the lock table size"。看起来可以通过更改 innodb_buffer_pool_size 来解决这个问题,但我决定也尝试另一种策略。令我震惊的是,如果我重新创建 table 并选择其中,我将避免此错误,并且也不会因弄乱索引字段而出现减速。

CREATE TABLE actions2 LIKE actions;
INSERT INTO actions2 (id, foreignkey, otherfields) SELECT id, TRIM(foreignkey), otherfields FROM actions;

如果我不事先禁用 table 的索引,此解决方案是否会比更新解决方案快得多?有没有我缺少的更快的方法?

编辑:此 table 的外键和其他 table 的主键是 VARCHAR(10) 字段。还有,我接受table只把最新的200万条记录一批加载到table,剩下的慢慢填充。

我会遍历 "chunks" 中的那个 table,一次大概做 1000 行。这是一些伪代码。 (详细信息取决于您希望使用的语言。)

$a = '';  -- assuming this is less than any value
loop...
    $z = SELECT v FROM main
        WHERE v > $a  ORDER BY v  LIMIT 1000,1;  -- efficient locate stopper
    BEGIN;
    -- Update each table
    UPDATE main SET v = TRIM(v)
        WHERE v > $a AND v <= $z;
    UPDATE table2 SET v = TRIM(v)
        WHERE v > $a AND v <= $z;
    UPDATE table3 SET v = TRIM(v)
        WHERE v > $a AND v <= $z;
    COMMIT;   -- this keeps anyone from stumbling over FKs in transition
    if finished, exit loop
    $a = $z
end loop

More discussion.

我随便选了1000个。它可能小到足以对 运行 系统产生最小影响,但又大到不会永远消失。

注意:如果您已经有一些修剪后的值,您可以前往 "duplicate key" 吗?