添加FK后,以下add index
代码是否冗余?
ALTER TABLE main ADD FOREIGN KEY (language_id) REFERENCES main_language (id);
ALTER TABLE main ADD INDEX (language_id);
为什么或为什么不呢?
答案 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);