MySQL是否自动索引外键列?


Answers:


229

是的,但仅限于 。Innodb是当前唯一实现外键的表格式。


1
您是否有理由相信MySQL会允许其他表类型的未索引列上使用外键?
罗伯特·格兰伯

我真的无法回答。您可能想要查找将在MySQL 6.0中发布的Maria和Falcon存储引擎,并查看它们是否支持非索引列上的外键。
格兰特·林伯格

显然这是不正确的。我有一张大桌子(一百万条记录)和count(*),其中fkey =?需要15秒。在fkey列上添加了一个索引,现在事情还不到一秒钟。
AbiusX '02

另一个表和1000万条记录的相同实验。这是MySQL 5.1 InnoDB。该表具有三个字段,一个是主键整数,另一个已被索引。第三个是另一个表的主键的外键。在不添加显式索引的情况下,查找花费了几秒钟。从表显示索引也未在其上显示索引。
AbiusX '02

@AbiusX 5.1可能太旧了,请参阅下面的MrAlexander回答。
e2-e4

131

显然,索引是根据robert发布​​的链接中的指定自动创建的。

InnoDB要求在外键和引用键上建立索引,以便外键检查可以快速进行,而无需进行表扫描。在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。如果这样的索引不存在,则会在引用表上自动创建。(这与某些旧版本相反,在旧版本中,必须显式创建索引,否则将无法创建外键约束。)如前所述,如果使用index_name,则使用它。

InnoDB和外键约束


9
+1更好的答案不是一个选择从文档提供的证据
Gaz_Edge

6
引用的文本似乎不再包含在MySQL文档中,因此不清楚是否仍然正确。
Courtney Miles

7
@ user2045006,您可以参考doc 5.0doc 5.6以获取确切的引用文本
sactiw

1
在当前文档中,文本仅InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
作了


11

如果您执行ALTER TABLE(而不是CREATE TABLE),则至少根据文档不会自动获得索引(链接用于5.1,但对于5.5相同):

[...]使用ALTER TABLE将外键约束添加到表时,请记住首先创建所需的索引。


2
我还在MySQL 5.6和MariaDB 10上尝试过,ALTER TABLE创建了一个索引。有趣的是,mysqlindexcheck报告该索引为“冗余索引”。我试图删除它,但出现以下错误:“错误1553(HY000):无法删除索引'index_name':在外键约束中需要”。因此,不可能删除该索引并保留外键。
西皮安·斯托伊卡

您可能需要修改答案。MySQL 总是创建一个索引来加速外键检查(如果尚不存在)。文档试图告诉您在外键约束之前创建索引可能会加快速度。例如,InnoDB可以使用可以用作外键检查索引的组合键索引,而不是自动生成冗余索引。
BMiner

7

对于那些正在寻找5.7 docs报价的人:

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


4

如前所述,它适用于InnoDB。起初,我以为很多其他功能(尤其是MS SQL和DB2)没有提供功能很奇怪。仅当表行很少时,TableSpace扫描才比索引扫描好-因此,在大多数情况下,希望对外键进行索引。然后这让我感到震惊-这不一定意味着它必须是独立的(一列)索引-它在MySQL的自动FK索引中。因此,可能是MS SQL,DB2(我不确定Oracle)等将其留给DBA的原因;大型表上的所有多个索引都可能导致性能和空间问题。


您提出了有关组合键索引的要点;但是,如果新创建的复合键索引履行了快速进行外键检查的义务,MySQL将自动/静默删除自动生成的单键索引。老实说,我不知道为什么MS SQL,DB2和其他人不这样做。他们没有什么借口。我想不出一个用例,在该用例上,自动生成的外键索引将是有害的。
BMiner

2

是的,Innodb提供这个。您可以在FOREIGN KEY子句后放置一个外键名称,也可以保留它以让MySQL为您创建一个名称。MySQL自动使用foreign_key_name名称创建索引。

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action

0

是的,当您创建一个具有到另一个表的外键的表时,Mysql会自动索引外键。


-2

无法自动使用索引键

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

您创建的表的名称,例如照片,以及FOREIGN KEY photograph_id。代码应该是这样的

ALTER TABLE photographs ADD INDEX (photograph_id);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.