我想通过例子来解释我的问题。我有一个长时间运行的语句像大的更新[...]从根源并行更新/删除死
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
此声明大表运行(其中两个含有每桌7+万行)。更新运行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
S于<table_C>
... <table_E>
正在处理中。
这通常不是一个好主意,使活动数据库上这么大的更新。例如,您可以将您的重大更新分解为几个较小的更新。 – Anri 2013-02-16 21:11:54
这对我来说是没有选择的,因为我必须知道,“product_id”必须不在任何一个表中。“#'......''。我已经尝试了你的建议,但是它们中最大的表包含了超过700万行,这足以导致lockwait超时(无论事实如果其他两个表也是'JOIN'ed) –
rabudde
2013-02-16 21:22:56
检查我的答案是否与你尝试过的不同。 – Anri 2013-02-16 21:49:02