【问题标题】:alter table query taking too long for adding constraint更改表查询添加约束花费的时间太长
【发布时间】:2014-10-01 04:51:24
【问题描述】:

我想更改一个名为 person 的表,并希望使用 office 表向它添加外键

我使用的查询是

ALTER TABLE person
ADD CONSTRAINT person_Office_FK
FOREIGN KEY ( Office_id )
REFERENCES Office ( Office_id ) ;

office 大约有 500,000 行,表 person 大约有 500 万行

这个查询一直持续,我不确定发生了什么。

【问题讨论】:

  • 永远,这听起来很长。你能说得更具体点吗?
  • 顺便说一句,我认为这在某种程度上是意料之中的,因为它需要交叉检查 很多 行。
  • forever 意味着我从过去 45 分钟开始运行此查询,我不确定发生了什么以及需要多长时间..
  • 我不知道 MySQL 是否有这个,但是在 MS-SQL 中你可以指定 WITH NOCHECK 它将创建外键而不检查你现有的数据以确保它符合。它只适用于未来的数据。这也意味着它不会“永远”。现在,您的数据库正在检查您的 person 表中的每一行,以确保它在 Office 表中具有匹配的 Office_id。

标签: mysql sql


【解决方案1】:

如果Office_idOffice 的主键,请确保它具有(主键)索引。这肯定会加快约束的添加速度。

另外,根据How to temporarily disable a foreign key constraint in MySQL?,你可以使用

SET FOREIGN_KEY_CHECKS=0;

要禁用所有外键约束检查,添加它们时可能也可以。

【讨论】:

    【解决方案2】:

    在添加约束之前,请确保 office 表的 office_id 上有一个聚集索引,而 person 表的 office_id 上有一个非聚集索引。

    请记住,person 表中每次出现 office_id 都需要检查每个 office_id 记录。如果您必须删除办公记录,这也会加快处理速度。

    您不想禁用检查,因为您的约束将不受信任,并且您不会获得外键在查询优化器中为您提供的性能优势。

    【讨论】:

    • MySQL 没有受信任/不受信任约束的概念,例如 Microsoft SQL Server(截至目前)。
    【解决方案3】:

    你可以使用:

    SET FOREIGN_KEY_CHECKS=0;
    

    不过,我通常会在执行此操作之前进行自己的外键检查:

    SELECT
      Person.*
    FROM person
    LEFT JOIN Office ON (person.Office_id = Office.Office_id)
    WHERE Office.Office_id IS NULL
    ;
    

    如果您可以安全地关闭 FOREIGN_KEY_CHECKS,该查询应该不会返回任何内容。

    【讨论】:

      【解决方案4】:

      这个问题仍然没有过时。我刚刚在这里遇到了同样的问题,并通过 5 个步骤找到了解决方法:

      1. 复制表格:CREATE TABLE table2 LIKE table1;

      2. 应用约束外键:ALTER TABLE..FOREIGN.... bla bla bla

      3. 将数据从table1转储到table2:INSERT INTO table2 SELECT * FROM table1;

      4. 删除表1:DROP TABLE table1;

      5. 重命名table2:RENAME TABLE table2 TO table1;

      一体化:

      CREATE TABLE table2 LIKE table1;
      ALTER TABLE..FOREIGN.... bla bla bla;
      INSERT INTO table2 SELECT * FROM table1;
      DROP TABLE table1;
      RENAME TABLE table2 TO table1;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 2015-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        相关资源
        最近更新 更多