Join

使用 FK 列、JOIN 和 LIMIT 從表中刪除

  • September 29, 2018

下面的這個查詢永遠不會完成,因為它總是查看前 100,000 個(user_type,user_ids)。如何編寫此程式碼以從具有 FK 引用(產品)到 UserTable 表的表中刪除 100,000 條記錄?換句話說,限制應該在連接之後發生,但最好以一種有效的方式?UserTable 在 (user_type, user_id) 和 (shard_key) 上有一個索引,而 Product 在 (user_type, user_id) 上有一個索引

它不一定必須是 100,000 - 例如,每個使用者最多可以擁有 100 個產品,如果刪除的記錄是(平均產品數量 * 100,000),那就沒問題了

DELETE p.*
FROM (
   SELECT user_type, user_id
   FROM UserTable
   WHERE MOD(shard_key,20) != 7
   LIMIT 100000
) t
JOIN Product p ON (
   t.user_type = p.user_type AND t.user_id = p.user_id
)

編輯:這是 MySQL 5.6

這個解決方法對我來說是可以的,但不是很好,因為它需要掃描使用者表的整個索引,所以不會很便攜。使用者與產品的比例可以達到1:1000,在JOIN之前先使用覆蓋索引掃描使用者表是可行的。

DELETE 
FROM Product f 
JOIN ( 
   SELECT t.* FROM (
       SELECT DISTINCT user_type, user_id
       FROM UserTable
       WHERE MOD(shard_key,20) != 7
       ) p
       JOIN Product t ON (
           t.user_type = p.user_type 
           AND 
           t.user_id = p.user_id
       ) LIMIT 10 
   ) x 
ON 
x.user_type = f.user_type 
AND 
x.user = f.user_id;

我的收穫是:如果您可以合理地使用索引快速掃描整個主鍵表,然後與外鍵表連接(理想情況下也使用索引),那麼這是一個確保您能夠找到所有外鍵引用的解決方案,如果您想在許多外鍵引用每個主鍵的情況下批量刪除。在這種情況下,使用者表約為 1GB,產品表約為 350GB

引用自:https://dba.stackexchange.com/questions/218855