外键是否自动创建索引?

Nic*_*ore 362 sql-server

MS SQL Server 2000

我对于提出这个问题感到愚蠢,但我被告知如果我将两个表外键,那么SQL Server将创建类似于子表中的索引的东西.我很难相信这是真的,但找不到那里特别相关的东西.

我之所以提出这个问题的真正原因是因为我们在一个删除语句中遇到了一个非常慢的响应时间,这个表可能包含15个相关表.我问过我们的数据库人,他说如果字段上有外键,那么它就像一个索引.你有什么经历?我应该在所有外键字段上添加索引还是只是不必要的开销?

mar*_*c_s 320

外键是约束,是两个表之间的关系 - 与索引本身无关.

但是已知的事实是,将所有列作为任何外键关系的一部分的索引很有意义,因为通过FK关系,您通常需要查找相关表并基于提取某些行单个值或一系列值.

因此,对FK中涉及的任何列进行索引是很有意义的,但FK本身不是索引.

查看Kimberly Tripp的优秀文章"SQL Server何时停止在外键列上放置索引?" .

  • 可能存在混淆,因为MySQL InnoDB在您添加外键时都需要并自动创建索引 - http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html (16认同)
  • @vsingh:这正是文章试图传达的内容 - 这是一个常见的误解**,FK会自动创建一个索引 - 它不会**那样做. (7认同)
  • @MBCook不,PostgreSQL确实*不*(至少在9.2或任何先前版本中)自动在用`REFERENCES`定义的外键关系的引用端创建索引.它自动为`PRIMARY KEY`或`UNIQUE`约束创建一个`UNIQUE`索引,并要求为外键关系的*引用*结束存在`UNIQUE`索引,但对于*引用不会自动执行任何操作*结束,尽管自己制作一个通常是个好主意.请参阅http://stackoverflow.com/questions/970562/postgres-and-indexes-on-foreign-keys-and-primary-keys (4认同)

Yis*_*hai 40

哇,答案都在地图上.所以文档说:

FOREIGN KEY约束是索引的候选者,因为:

  • 使用相关表中的FOREIGN KEY约束检查对PRIMARY KEY约束的更改.

  • 当来自相关表的数据通过将一个表的FOREIGN KEY约束中的列与另一个表中的主键或唯一键列相匹配时,外键列通常用于连接条件.索引允许Microsoft®SQLServer™2000快速查找外键表中的相关数据.但是,创建此索引不是必需的.即使表之间没有定义PRIMARY KEY或FOREIGN KEY约束,也可以组合来自两个相关表的数据,但是两个表之间的外键关系表明这两个表已被优化以组合在使用键的查询中它的标准.

所以看起来很清楚(尽管文档有点混乱),它实际上并没有创建索引.

  • 确切地说 - 它是一个*CANDIDATE*的索引 - 但它不会自动创建为一个!实际上很清楚,恕我直言:-) (4认同)
  • 我发现这一部分混乱:"两个表之间的外键关系表明这两个表已经过优化,可以在一个使用密钥作为标准的查询中进行组合." 这应该是"......两个表应该优化......" (4认同)

Mic*_*rdt 18

不,外键字段没有隐式索引,否则为什么微软会说"在外键上创建索引通常很有用".您的同事可能会将引用表中的外键字段与引用表中的主键混淆 - 主键确实会创建隐式索引.


Gre*_*gor 10

在 PostgeSql 中,如果您点击 \d 表名,您可以自己检查索引

您将看到已在具有主键和唯一约束的列上自动创建 btree 索引,但不会在具有外键的列上创建。

我认为这至少对于 postgres 来说回答了你的问题。


Pau*_*ier 7

SQL Server自动创建主键的索引,但不为外键自动创建索引.为外键创建索引.它可能值得开销.


And*_*mar 6

假设您有一个名为orders的大表,以及一个名为customers的小表.从订单到客户有一个外键.现在,如果删除客户,Sql Server必须检查是否没有孤立订单; 如果有,它会引发错误.

要检查是否有任何订单,Sql Server必须搜索大订单表.现在如果有索引,搜索速度会很快; 如果没有,搜索将会很慢.

所以在这种情况下,缓慢删除可以通过缺少索引来解释.特别是如果Sql Server必须在没有索引的情况下搜索15个大表.

PS如果外键具有ON DELETE CASCADE,则Sql Server仍然必须搜索订单表,然后删除任何引用已删除客户的订单.


小智 6

外键不创建索引。仅备用键约束(UNIQUE)和主键约束创建索引。在Oracle和SQL Server中都是如此。


小智 5

这取决于。在 MySQL 上,如果您不自己创建索引,则会创建索引:

MySQL要求外键列建立索引;如果创建具有外键约束但给定列上没有索引的表,则会创建索引。

来源:https ://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html

MySQL 5.6 也是如此。