2014-11-05 70 views
2

這裏是一些mysql inno_bd表t主鍵id和多個btree三個字段的索引。 場A,B,C分別 是intintDatetable 問題是出在以下幾點: 有存檔t_archive表,我用它來記錄從t移動到t_archive如果已經過時。要移動記錄我用兩個查詢:mysql innodb多個索引鎖查詢過多行

  • INSERT INTO t_archive SELECT * FROM t WHERE A = 1 AND B = 2 AND C = 3
  • DELETE FROM t WHERE A = 1 AND B = 2 AND C = 3

(正如您所注意到,滿足條件的id是4和5) 在上述查詢我嘗試UPDATE recods與ids:1和8. 邏輯上,沒有理由lock記錄1,2,3,3,6,7,8鑽出任何類型的查詢, 但它發生! 因爲真正的紅色部分比例如,在更大的,轉移操作需要很多時間(約50秒),我不能與其他地區經濟共同體的工作(只更新其中id = 8) - 得到一個例外:Lock wait timeout exceeded; try restarting transaction

任何人都可以解釋爲什麼會發生,以及如何避免它?

回答

0

問題消失,如果使用更棘手DELETE查詢:

DELETE t FROM my_table t, 
(SELECT t1.id AS del_id FROM my_table t1 
WHERE t1.A=1 
AND t1.B=2 
AND t1.C=3) AS del 
WHERE t.id=del.del_id; 
+0

對發生的事情的解釋很棒:) – artaxerxe 2015-12-08 10:51:47

0

如果這是一個「大」表,如果你有沒有合適的索引,如INDEX(a,b,c)(以任意順序),則DELETE需要很長時間才能掃描桌子,在獲取桌子時掛在鎖上。這會面臨鎖定等待超時或甚至死鎖的風險。

如果表格「很小」和/或您有一個好的索引,超時是否發生?

返回爲什麼DELETE使用子查詢得到ids的問題可能是創傷小:

首先SELECT子查詢以最小的鎖運行。然後運行DELETE,需要對至少2行進行排它鎖定。如果它沒有超時,我懷疑這是因爲在這個「2步」版本中獲取鎖的時間。