Mysql 大更新[…]从中选择导致并行更新/删除死亡

Mysql 大更新[…]从中选择导致并行更新/删除死亡,mysql,select,locking,sql-update,table-locking,Mysql,Select,Locking,Sql Update,Table Locking,我试图用例子来解释我的问题。我有一个长期的声明,比如 UPDATE <table_A> INNER JOIN <table_B> ON [...] LEFT JOIN <table_C> ON [...] LEFT JOIN <table_D> ON [...] LEFT JOIN <table_E> ON [...] SET <table_A>.<col_A>=X WHERE <table_A>.&

我试图用例子来解释我的问题。我有一个长期的声明,比如

UPDATE <table_A>
INNER JOIN <table_B> ON [...]
LEFT JOIN <table_C> ON [...]
LEFT JOIN <table_D> ON [...]
LEFT JOIN <table_E> ON [...]
SET <table_A>.<col_A>=X
WHERE <table_A>.<col_A>=Y AND COALESCE(<table_C>.<id>,<table_D>.<id>,<table_E>.<id> IS NULL

但那没用。上的数据一致性并不是那么重要,如果它包含的行在。。。不再最重要的是,在…上的小更新/删除。。。正在处理中。

由于在实时数据库上运行如此大的更新通常不是一个好主意,我建议您将大的更新分解

这里不是最优化的方法,但我相信您自己会设法优化它

循环运行:

从表A中选择Id,ColA按Id顺序描述限制10偏移迭代*10 第二个循环,从tableA.colA=Y的上一个结果中获取行 2.1. 从表B中选择Id,其中Id=当前迭代中的Id 2.2. 从表C中选择Id,其中Id=当前迭代中的Id 2.3如果之前的两个查询都返回null,则转到下一步,否则继续下一次迭代 2.4更新TableA集合ColA=X,其中ID=ID\u来自当前迭代 换句话说,避免连接。 这将需要比单个更新更长的时间,但它可以工作。
优化它的第一步是批处理查询。

在实时数据库上进行如此大的更新通常不是一个好主意。例如,你可以将你的大更新分解为几个小的更新。这对我来说是没有选择的,因为我必须知道产品id必须不在任何一个表中。。。。我已经尝试过你的建议,但是其中最大的一个表包含700多万行,这足以导致锁定等待超时,不管其他两个表是否也连接在一起。检查我的答案是否与你尝试过的不同。好的,你已经拆分了连接,这不是我的意图,但理论上应该能解决问题,所以你的答案是可以接受的。出现问题的原因是我将UPDATE与join结合在一起,这会锁定行。我现在已经将更新更改为10000步循环id。每次循环运行2-3秒,现在我的体验好多了。
UPDATE <table_C> SET <col_A>=Z WHERE <id> IN ([...])
DELETE FROM <table_C> WHERE <id> IN ([...])
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
[BIG UPDATE];
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;