我想删除在活动或照片或电子邮件订阅者中不存在的人。也许他们是,但他们被标记的唯一照片被删除,或他们所处的事件被从数据库中清除。
两个明显的选择:
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
A& A P大约一百万行,E几千。
第一个选项工作正常,大约需要10秒钟。
第二个选项超时。
是否有更聪明,更好,更快的第三选择?
答案 0 :(得分:3)
这就是我要做的事情,例如,如上所述的数百万行半虚构架构。
对于这个人,我会添加与子表相关的计数列,每个1和一个日期时间。如
photoCount INT NOT NULL,
...
lastUpdt DATETIME NOT NULL,
当对子表进行INSERT / UPDATE时(主要焦点自然是插入),我会
people
)行lastUpdt=now()
对子行的删除与上面一样,但是有一个减量。
这些是否已完成客户端/存储过程/触发器是您的选择。
让活动看到1和2每周发布一次(您选择的频率),删除lastUpdt大于1周的people
行,并且计数列全部在零。
我意识到Intention Lock不是一个完全类比,但关于超时和行级锁定以及对速度的需求是相关的。
考虑到系统的使用频率,真正的好处和潜在的拖拽,一如既往地精心制作您的索引。
对于任何定期清理事件,请使用调度程序安排它们在低峰值时间运行。
所有这些都有一些自然的缺点。但是,如果这些摘要数字对其他个人资料页面有用,并且即时获取它们代价太高,那么您将受益匪浅。此外,你肯定会回避我在你提出的两个解决方案中看到的昂贵的电话。
答案 1 :(得分:1)
我尝试使用postgreSQL复制你的场景。但我认为还有其他事情你没告诉我们。
A& A P大约一百万行,E几千。
表people
= 10k记录
我随机选择9500记录并插入email_subscriptions
然后将{95}条记录复制100次attendees
和photo_tags
每张表格总计950k
<强> SQL FIDDLE DEMO 强>
首次查询需要5秒左右 第二个需要11毫秒。