外键是否自动创build索引?
MS SQL Server 2000
我对这个问题感到无聊,但是我被告知,如果我外键键入两个表,那么SQL Server将创build类似于子表中索引的东西。 我很难相信这是真实的,但是在这方面没有什么特别的地方。
我问这个问题的真正原因是因为在一个可能有15个相关表的表的delete语句中,我们正在经历一些非常慢的响应时间。 我问过我们的数据库的人,他说,如果在字段上有一个外键,那么它就像一个索引。 你有什么经验呢? 我应该在所有外键字段上添加索引,还是只是不必要的开销?
外键是一个约束,是两个表之间的关系 – 与索引本身无关。
但是,众所周知,索引属于任何外键关系的所有列是非常有意义的,因为通过FK关系,您经常需要查找关联表并根据一个值或一个值的范围。
因此,索引FK中涉及的任何列是很有意义的,但FK本身不是索引。
查看Kimberly Tripp的优秀文章“SQL Server何时停止在外键列上放置索引? 。
哇,答案都在地图上。 所以文档说:
FOREIGN KEY约束是索引的候选者,因为:
-
PRIMARY KEY约束的更改在相关表中使用FOREIGN KEY约束进行检查。
-
通过将一个表的FOREIGN KEY约束中的列与另一个表中的主键或唯一键列进行匹配,将相关表中的数据组合到查询中时,通常在连接条件中使用外键列。 索引允许Microsoft®SQL Server™2000快速在外键表中查找相关数据。 但是,创build此索引不是必需的。 即使两个表之间没有定义PRIMARY KEY或FOREIGN KEY约束,但是两个表之间的外键关系指示这两个表已经被优化以在使用键的查询中组合其标准。
所以看起来很清楚(虽然文档有点混乱),实际上并没有创build索引。
不,对外键字段没有隐式索引,否则为什么微软会说“在外键上创build索引通常是有用的” 。 您的同事可能会将引用表中的外键字段与引用表中的主键混淆 – 主键会创build隐式索引。
假设你有一个叫做订单的大表,还有一个叫做客户的小表。 从订单到客户有一个外键。 现在,如果你删除了一个客户,Sql Server必须检查没有孤儿命令; 如果有的话,会引发错误。
要检查是否有任何命令,Sql Server必须search大订单表。 现在如果有索引,search速度会很快; 如果没有,search会很慢。
所以在这种情况下,缓慢的删除可以通过没有索引来解释。 特别是如果Sql Server将不得不search没有索引的15个大表。
PS如果外键具有ON DELETE CASCADE,Sql Server仍然需要search订单表,但是删除引用删除的客户的任何订单。
不是我的知识。 外键仅添加一个约束,即子键中的值也可以在父列中的某个位置表示。 它不告诉数据库,子键也需要被索引,只有约束。
SQL Server自动为主键创build索引,但不能为外键创build索引。 为外键创build索引。 这可能是值得的开销。
外键不创build索引。 只有备用键约束(UNIQUE)和主键约束才能创build索引。 这在Oracle和SQL Server中是正确的。
严格来说,外键与索引完全没有关系,是的。 但是,正如上面的发言者指出的那样,创build一个加速FK查找是有意义的。 事实上,在MySQL中,如果你没有在你的FK声明中指定一个索引,引擎(InnoDB)会自动为你创build它。
我注意到指向MSSQL的Entity Framework 6.1会自动在外键上添加索引。
在PostgeSql中,如果你点击\ d表名,你可以自己检查索引
您将看到btree索引已经自动创build在具有主键和唯一约束的列上,而不是在具有外键的列上。
我认为这至less为postgres回答你的问题。