2015-04-17 28 views
2

我有一個cron安裝程序,用於生產mysql表的備份,並定期從表中清除表中的數據。我必須刪除ID引用的多個表中的數據。從mysql表中清除數據

一些背景:我需要刪除大約200萬行,我的應用程序將不斷的讀/寫我的數據庫(它不應該通常訪問的行被刪除,雖然)

我的問題是我應該如何在以下參數上構建我的刪除查詢:

  1. 在單個批量查詢中刪除vs批量刪除?
  2. 在單個事務中的不同表中刪除vs刪除而不使用任何事務。如果我在交易中使用刪除,即使我批量刪除,是否還有任何表級鎖?
  3. 我沒有任何分區設置,會碎片化的問題?

回答

0

假設:

  1. 隔離級別:可重複讀 - MySQL默認隔離級別。
  2. 刪除您擁有的查詢基於範圍而不是主索引。

  3. 刪除一個事務中的所有行, 將會有非常長的事務和更大的鎖。這會增加複製延遲,複製延遲很糟糕,新的DC使它非常糟糕。擁有更大的鎖也會降低您的寫入吞吐量。 (在隔離級別可串行化的情況下,即使讀取吞吐量也可能受到影響。)

  4. 批量刪除。 比刪除所有更好,但作爲範圍刪除,每個刪除的鎖的數量會更多,(將採取間隙鎖和下一行鎖)。所以在批量範圍內刪除也會有相同的問題,只是更小。

相比於全部刪除和批量刪除,最好是批量刪除。

其他做法:(我們需要刪除之前的行) 1.有一個守護進程運行每個configured_time和。 i。從表中選擇pk,其中清除時間爲<您的清除時間。 - 沒有鎖 ii。基於pk刪除,使用多線程。 - 行級鎖,小事務(跨表)。

此方法將確保更小的事務並且只保留行級鎖。 (基於主鍵的刪除只會進行行級鎖定)。此外,您的查詢很簡單,所以即使刪除部分成功,您也可以重新運行。我覺得這些原子不是必需的。

或者

  • 減少您的隔離級別:要READ_COMMITED那麼即使與批量刪除你應該罰款。在讀取COMMITED隔離時,即使通過輔助鍵訪問,鎖也只在行上。
  • 或者

  • 如果你的模型允許基於時間碎片落分貝本身:)