我有一个大表(数百万行),我想用SELECT setval('my_sequence_name', max(mycolumn))
FROM myschema.mytable;
替换VARCHAR
列中的所有值,这将是指向新表的外键保留所有INT
值。如果重要的话,VARCHAR
值是唯一的。
此刻,我可以使用以下命令有效地创建外部表:
VARCHAR
但是我第一次替换VARCHAR列的基本尝试效率极低,并且每行花费几秒钟,这显然不可行(INSERT INTO `messages` (`message`) SELECT `message` FROM `history`;
可以进行测试)。
LIMIT
感觉我应该能够完全用SQL来完成此过程,而不是依赖PHP,希望这也是一种有效的方法。
答案 0 :(得分:3)
您可以使用UPDATE ... JOIN
查询来让您的RDBMS一次完成繁重的工作,而不是使用PHP循环:
UPDATE history h
INNER JOIN messages m ON m.message = h.message
SET h.message = m.id
这假定表messages
已经送入。为了获得更好的性能,由于您声明列message
中的值是唯一的,因此您可能想在UNIQUE
上创建messages(messsage)
约束。
答案 1 :(得分:1)
您必须使用php吗?因为您正在: 1)一个请求带来100行 2)对于每一行,一个请求携带另一个表的ID,然后另一个请求更新原始表。而且我认为原始表大于100行。
您不能直接在数据库内部进行操作吗?如果varchar值是唯一的,而您想要的只是将它们放在单独的表中,则可以像您一样填充新表,但还要指定id,这将很方便地与原始表的id相同:< / p>
INSERT INTO `messages` (`id`, `message`) SELECT `id`, `message` FROM `history`;
然后,创建一个新的INT列,该列将保存外键:
ALTER TABLE history ADD message_id INT;
然后,填充列:
UPDATE history SET message_id = id;
然后删除varchar列:
ALTER TABLE history DROP message;
您现在可以添加约束,以指示message_id是外键:
ALTER TABLE history ADD CONSTRAINT fk_message_id FOREIGN KEY message_id REFERENCES messages(id);
通过这种方式,您只需进行两次迭代:一次用于填充新表,另一次用于设置新列。