我试图通过例子来解释我的问题。我有一个长期运行的声明,如
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
此语句在大表上运行(其中两个表每行包含700多万行)。更新运行3-5分钟。在另一个会话中,以高并发性完成
UPDATE <table_C> SET <col_A>=Z WHERE <id> IN ([...])
或
DELETE FROM <table_C> WHERE <id> IN ([...])
当大UPDATE
运行时,这些并发UPDATE
和DELETES
会在一到两分钟后死锁,并发生锁定等待超时或死锁。所有JOIN
列都已编制索引(标准索引)。
我已经尝试过了
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
[BIG UPDATE];
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
但这没有用。 <table_A>
上的数据一致性并不那么重要(如果它包含<table_C>
... <table_E>
中不存在的行,则没有问题。最重要的是,正在处理UPDATE
... DELETE
上的小型<table_C>
/ <table_E>
。
答案 0 :(得分:0)
由于在实时数据库上运行这么大的更新通常是一个坏主意,我建议你打破你的大更新。
这不是最优化的方法,但我相信你会设法自己优化它。
循环运行:
SELECT Id, ColA FROM TableA ORDER BY Id DESC LIMIT 10 OFFSET (iteration)*10
tableA.colA=Y
的前一个结果中取出行
2.1。 SELECT Id FROM TableB WHERE ID=id_from_current_iteration
SELECT Id FROM TableC WHERE ID=id_from_current_iteration
UPDATE TableA SET ColA=X WHERE ID=id_from_current_iteration
换句话说 - 避免加入 这将花费比单次更新更长的时间,但它会起作用 优化它的第一步是批处理查询。