SQL:删除关联被破坏的行(孤立数据)

发布于 2024-11-07 21:30:37 字数 227 浏览 0 评论 0原文

我有一个名为“downloads”的表,其中有两个外键列——“user_id”和“item_id”。我需要从该表中选择所有行,并删除相关用户或项目不再存在的行。 (查找 User,如果没有找到,则删除“downloads”中的行,然后查找 Item,如果没有找到,则删除“downloads”中的行)。

它有 340 万行,因此我所有的脚本解决方案都花费了 6 个多小时。我希望有一种更快的、仅 SQL 的方法来做到这一点?

I have a table called "downloads" with two foreign key columns -- "user_id" and "item_id". I need to select all rows from that table and remove the rows where the User or the Item in question no longer exists. (Look up the User and if it's not found, delete the row in "downloads", then look up the Item and if it's not found, delete the row in "downloads").

It's 3.4 million rows, so all my scripted solutions have been taking 6+ hours. I'm hoping there's a faster, SQL-only way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

把昨日还给我 2024-11-14 21:30:37

使用两个反连接和or 将它们放在一起:

delete from your_table
where user_id not in (select id from users_table)
or item_id not in (select id from items_table)

完成后,考虑添加两个外键,每个外键都有一个删除级联子句。它会自动为你做这件事。

use two anti joins and or them together:

delete from your_table
where user_id not in (select id from users_table)
or item_id not in (select id from items_table)

once that's done, consider adding two foreign keys, each with an on delete cascade clause. it'll do this for you automatically.

以往的大感动 2024-11-14 21:30:37
delete from your_table where user_id not in (select id from users_table) or item_id not in (select id from items_table)
delete from your_table where user_id not in (select id from users_table) or item_id not in (select id from items_table)
陈年往事 2024-11-14 21:30:37

认为当有这么多行时没有更快的解决方案
在您的服务器上每秒 157 行

检查用户 ID
如果 mysql num rows = 0 则删除下载并检查 item_id

还有一个关于 myswl num rows 性能的类似问题

MySQL:计算行数的最快方法

工作

编辑:认为最好的方法是创建一些触发器,以便数据库服务器为您完成当前我将使用的 第一次执行 cronjob

think there is no faster solution when there are so many rows
that are on your server 157 rows per second

check user id
if mysql num rows = 0 than delete the downloads and also check the item_id

there was also a similar question about the performance of myswl num rows

MySQL: Fastest way to count number of rows

edit: think the best is to creatse some triggers so the database server does the job for you

currently i would use a cronjob for the first time

苄①跕圉湢 2024-11-14 21:30:37

备查。对于此类长时间操作。可以独立于 SQL 来优化服务器。例如,分离 sql​​ 服务,对系统磁盘进行碎片整理,如果您可以确保 sql 日志文件位于与数据库所在驱动器不同的磁盘驱动器上。
这至少会减少此类长时间手术的痛苦。

For future reference. For these kind of long operations. It is possible to optimise the server independently of the SQL. For example detach the sql service, defrag the system disk, if you can ensure the sql log files are on separate disk drive to the drive where database is.
This will at least reduce the pain of these kind of long operations.

瞎闹 2024-11-14 21:30:37

我在 SQL 2008 R2 中发现,如果您的“in”子句包含空值(可能来自引用该可为空键的表),则不会返回任何记录!要更正,只需在 union 部分的选择中添加一个子句:

delete from SomeTable where Key not in (
  select SomeTableKey from TableB where SomeTableKey is not null
  union
  select SomeTableKey from TableC where SomeTableKey is not null
)

I've found in SQL 2008 R2, if your "in" clause contains a null value (perhaps from a table who has a reference to this key that is nullable), no records will be returned! To correct, just add a clause to your selects in the union part:

delete from SomeTable where Key not in (
  select SomeTableKey from TableB where SomeTableKey is not null
  union
  select SomeTableKey from TableC where SomeTableKey is not null
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文