MYSQL中的外键索引

时间:2014-10-23 19:36:50

标签: mysql

添加FK后,以下add index代码是否冗余?

ALTER TABLE main ADD FOREIGN KEY (language_id) REFERENCES main_language (id);
ALTER TABLE main ADD INDEX (language_id);

为什么或为什么不呢?

1 个答案:

答案 0 :(得分:3)

是的,这是多余的。添加FOREIGN KEY约束隐式地在language_id上创建索引。如果你需要添加一个包含其他列的不同复合索引,那么它不会是多余的,而是单列。

ALTER TABLE main ADD FOREIGN KEY (language_id) REFERENCES main_language (id);

-- This is redundant
ALTER TABLE main ADD INDEX (language_id);

-- This is not redundant
ALTER TABLE main ADD INDEX (other_column, language_id);

According to MySQL docs,如果在创建FOREIGN KEY时已存在一个新的索引,则MySQL不会在FOREIGN KEY列上创建新索引。

  

MySQL需要外键和引用键上的索引,以便外键检查可以快速而不需要表扫描。在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。如果引用表不存在,则会自动在引用表上创建此索引。如果您创建另一个可用于强制执行外键约束的索引,则可以稍后以静默方式删除此索引。如果给定,则使用index_name,如前所述。

因为索引列是从左到右使用的,如果已经在列上有此索引,则创建FOREIGN KEY约束不需要创建新索引。

-- Already has a composite index with the FK column listed first
ALTER TABLE main ADD INDEX (language_id, other_column);
-- This won't create a new index when the constraint is defined
ALTER TABLE main ADD FOREIGN KEY (language_id) REFERENCES main_language (id);

修改: 根据上段中的这一说明:

  

如果您创建另一个可用于强制执行外键约束的索引,则可以稍后以静默方式删除此索引

...文档似乎暗示如果您创建了建议的冗余索引,MySQL可能会默默地删除它作为FORIEGN KEY约束的一部分隐式创建的索引,因为可以使用显式创建的索引。所以它可能不会继续维持两个指数。

同样,这表明添加上面的复合索引可能导致MySQL不再需要维护FK隐含创建的索引。

ALTER TABLE main ADD FOREIGN KEY (language_id) REFERENCES main_language (id);
-- Adding this later may allow MySQL to drop the implicit index created with the FK
ALTER TABLE main ADD INDEX (language_id, other_column);