我正在构建一个数据库并遇到一个问题,需要通过错误消息字段连接两个表,当前设置为varchar(255)。这(显然)会在执行连接时导致性能和锁定问题。我的初始陈述挂在任何大于1000行的更新上。这是代码:
UPDATE Integration_Detail D
JOIN Integration_Error_Descriptor E
ON D.Error_Message = E.Error_Message
SET D.Error_Key = E.Error_Key
WHERE D.Error_Key is null;
我决定更改为存储过程,以便将UPDATE语句分解为更小的部分。这是有效的,但在性能方面并不理想,因为我使用while循环并批量更新200.过程代码如下所示:
CREATE PROCEDURE update_detail_table()
BEGIN
declare rowsToProcess int default 0;
set rowsToProcess =
(select count(*)
from Integration_Report.Integration_Detail
where Error_Key is null);
CREATE TABLE Integration_Report.temp_error_processing (
Detail_Key bigint DEFAULT null,
Error_Key bigint DEFAULT null
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
while rowsToProcess > 0 DO
INSERT INTO Integration_Report.temp_error_processing
(SELECT D.Detail_Key, E.Error_Key
FROM Integration_Report.Integration_Detail D
JOIN Integration_Report.Integration_Error_Descriptor E
ON D.Error_Message = E.Error_Message
WHERE D.Error_Key is null
ORDER BY D.Insert_Datetime desc
LIMIT 200);
UPDATE Integration_Report.Integration_Detail D
JOIN Integration_Report.temp_error_processing T
ON D.Detail_Key = T.Detail_Key
SET D.Error_Key = T.Error_Key;
TRUNCATE TABLE Integration_Report.temp_error_processing;
set rowsToProcess =
(select count(*)
from Integration_Report.Integration_Detail
where Error_Key is null);
end while;
drop table Integration_Report.temp_error_processing;
END;
有没有办法实现更快,占用更少的内存?我之前没有写过很多程序,所以如果我的代码也很丑,请告诉我。
感谢您的帮助。
答案 0 :(得分:0)
你所拥有的块效率低的部分原因是它反复踩到完成的行。目标是每次查看不同的200行。
我在这里讨论细节:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
请注意,它会使用PRIMARY KEY
遍历表格,以避免重新扫描。并且它不一定每次处理完整的块。并且不需要COUNT(*)
,因为到达表的末尾就足以终止。