2016-10-04 29 views
-1

我想刪除不在活動中的人或照片或電子郵件訂閱者。也許他們是,但他們被標記的唯一照片被刪除,或者他們所在的事件從數據庫中清除。Mysql刪除ID在多個表中不存在 - 最佳實踐?

兩個顯而易見的選擇:

1)

DELETE FROM people 

WHERE personPK NOT IN (
    SELECT personFK FROM attendees 
     UNION 
    SELECT personFK FROM photo_tags 
     UNION 
    SELECT personFK FROM email_subscriptions 
) 

2)

DELETE people FROM people 

LEFT JOIN attendees A on A.personFK = personPK 
LEFT JOIN photo_tags P on P.personFK = personPK 
LEFT JOIN email_subscriptions E on E.personFK = personPK 

WHERE attendeePK IS NULL 
    AND photoTagPK IS NULL 
    AND emailSubPK IS NULL 

兩個一& P每人約一百萬行,和E幾千元。

第一個選項工作正常,需要10秒左右。

第二個選項超時。

有沒有更聰明,更好,更快的第三選擇?

+0

這可能是一個愚蠢的問題,但如果第一個選項有效,你可以使用它嗎?它不夠快嗎?如果是這樣,你在尋找什麼速度? – raphael75

+0

你確定要這樣做嗎?如果刪除發生但如果你想重新掛一張新照片怎麼辦? – Drew

+0

我確定德魯。這是一個半虛構的例子,但我的用例是堅實的。 – Codemonkey

回答

3

這就是我所要做的,比如上面的一個數百萬行半虛構的模式。

對於這個人,我會添加計數列,每個列與子表相關,以及日期時間。如

photoCount INT NOT NULL, 
... 
lastUpdt DATETIME NOT NULL, 

當談到時間上的子表的INSERT/UPDATE(重點自然是插入),我會

  1. 開始交易
  2. 執行「選擇更新」這使得對父的Intention Lockpeople)行
  3. 執行插入孩子,如一個新的圖片或電子郵件
  4. 增量父relevan噸計數變量和設定lastUpdt=now()
  5. 提交TRAN(其釋放意圖鎖)

甲刪除針對子行是像上面但具有遞減。

是否完成客戶端/存儲過程/觸發器是您的選擇。

發生事件請參閱12,每週會觸發一次(您選擇頻率)刪除people lastUpdt大於1周且計數列全部爲零的行。

我意識到意圖鎖定不是一個確切的類比,但關於超時和行級鎖定以及速度需求的觀點是相關的。

一如既往地精心制定您的指標,考慮使用頻率,真正的收益和潛在的拖延對系統。

對於任何定期清理事件,請安排它們在調度程序的低峯時段運行。

所有這些都有一些天然的缺點。但是,如果這些彙總號碼對其他配置文件頁面有用,並且在運行中提取它們代價太高,則您可以從中受益。您也肯定會迴避我在您提出的兩個解決方案中看到的昂貴通話。

1

我嘗試在這裏使用postgreSQL複製你的場景。但我認爲你還沒有告訴我們其他的東西。

兩個A & P每行約100萬行,E幾千。

people = 10K記錄
我選擇9500記錄在隨機插入email_subscriptions
然後複製那些9500個記錄100次attendeesphoto_tags總950K每桌

SQL FIDDLE DEMO

第一個查詢需要5秒
第二個需要11毫秒。

+0

每次我寫一個'UNION'我都不寒而慄。加上uno – Drew

+0

我認爲他沒有告訴我們的是至少有一個外鍵缺少索引。 – CptMisery

+0

@CptMisery並非如此,如果您同時從演示中刪除索引。 –