清理/修剪維度表中未引用的數據
我們有一個在 MySQL 5.6 上執行的星型模式數據倉庫。我們按月使用分區在事實表中保留 18 個月的滾動數據。我們有許多被多個事實表引用的動態維度表。但是,我們沒有簡單的方法從維度表中刪除不再被任何事實表引用的行。快速摘要如下所示:
dim_url - 1B rows - 360GB fact_ranks - 2.3B rows - 240GB fact_seen - 2.8B rows - 295GB
目前我們正在嘗試使用 Percona Archiver 和触發器的組合來生成“使用的維度鍵”表,因此我們可以線上完成該過程。然後我們使用鍵表來建構一個只有引用行的新維度。但是,我們無法在生產中完成此過程,估計可能需要長達一個月的時間。
這必須是一個更優雅的解決方案的常見問題。
(通常,我會說“不要打擾”。但我看到你的 Dim 表幾乎和 Fact 表一樣大。嗯……也許連 Dim 表都不明智??想想看。)
用於建構
Used
表(並假設觸發器處理傳入的插入):從事實表中,建構有用值列表 (
Used
)。一次執行一個塊,例如 1000 行,由PRIMARY KEY
. 此列表進入一個額外的表,Used
。每個塊一個事務。刪除重複數據並添加 PK。請參閱我對分塊的評論。現在,遍歷 Dim 表,一次可能只有 100 行,並執行多表刪除,
LEFT JOIN Used ... WHERE ... IS NULL
用於確定不需要的內容。小心——the
DELETE
和theTRIGGER
可能互相踩踏。也就是說,可能存在需要重新執行的死鎖。但是一次 100 行應該在最大限度地減少死鎖和最大限度地提高速度之間保持良好的平衡。每個塊一個事務。是的,這需要時間——無論是發現
Used
還是DELETEs
. 但這應該沒關係。其他一切都在嗡嗡作響,只有非常罕見和短暫的干擾。我想當一行插入時
TRIGGER
需要插入。Used``Dim
如何按新的“last_referenced_date”列(每月)對維度表進行分區?
- 該列將設置為記錄 INSERT 上的目前日期。
- 清理過程的第一次執行必須通過完整的事實表進行分塊 - 並適當地設置值(MySQL 將自動將數據移動到正確的分區)。
- 未來的執行只需要查看目前的事實數據(最近一個月?)。
- 然後,只需刪除最新日期早於最舊事實表日期的任何分區。