【问题标题】:Delete all not referenced (by foreign key) records from a table in mysql从mysql中的表中删除所有未引用(通过外键)的记录
【发布时间】:2015-02-11 15:25:39
【问题描述】:

我有一个从其他 6 个表(有时是多个表)引用的地址表。其中一些表有大约 50 万条记录(地址表大约有 750000 条记录)。我想运行一个定期查询,删除所有表中未引用的所有记录。

以下子查询不是一个选项,因为查询永远不会完成 - 范围太大。

delete from address where address_id not in (select ...)
and not in (select ...) and not in (select ...) ...

我希望我可以使用外键约束,并且我可以简单地删除外键约束不会阻止我的所有记录(因为没有对表的引用)。我找不到这样做的方法(或者有吗?)。还有其他好主意来解决这个问题吗?

【问题讨论】:

    标签: mysql database


    【解决方案1】:

    你可以试试这个方法

    DELETE
        address
    FROM
        address
        LEFT JOIN other_table ON (address.id = other_table.ref_field)
        LEFT JOIN other_table ON (address.id = other_table2.ref_field)
    WHERE
        other_table.id IS NULL AND other_table2.id IS NULL
    

    DELETE 
    FROM address A
    WHERE NOT EXISTS (
      SELECT 1
      FROM other_table B
      WHERE B.a_key = A.id
    )
    

    【讨论】:

      【解决方案2】:

      我总是用这个:

      DELETE FROM table WHERE id NOT IN (SELECT id FROM OTHER table)
      

      【讨论】:

        【解决方案3】:

        我首先创建一个临时表 (t),它是 6 个引用表中 ID 的 UNION,然后运行:

        DELETE x FROM x LEFT JOIN t USING (ID) WHERE x.ID IS NULL;
        

        其中 x 是地址表。

        请参阅此处的“多表语法”: http://dev.mysql.com/doc/refman/5.0/en/delete.html

        显然,您的临时表应该在 ID 上有它的 PRIMARY KEY。查询和加入可能需要一些时间,但我看不到绕过它的方法。它应该被优化,不像多子查询版本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-22
          • 1970-01-01
          • 2011-02-16
          • 1970-01-01
          相关资源
          最近更新 更多