我被告知,如果我外键两个表,SQL Server将在子表中创建类似于索引的东西。我很难相信这是真的,但找不到太多与此相关的具体信息。
我问这个问题的真正原因是,对于一个可能有15个相关表的表,我们在delete语句中遇到了一些非常慢的响应时间。我问过我们数据库的人,他说如果字段上有外键,它就像一个索引。你在这方面有什么经验?我是否应该在所有外键字段上添加索引,或者它们只是不必要的开销?
我被告知,如果我外键两个表,SQL Server将在子表中创建类似于索引的东西。我很难相信这是真的,但找不到太多与此相关的具体信息。
我问这个问题的真正原因是,对于一个可能有15个相关表的表,我们在delete语句中遇到了一些非常慢的响应时间。我问过我们数据库的人,他说如果字段上有外键,它就像一个索引。你在这方面有什么经验?我是否应该在所有外键字段上添加索引,或者它们只是不必要的开销?
外键是一种约束,是两个表之间的关系——本质上与索引无关。
但是,索引作为任何外键关系一部分的所有列非常有意义。fk关系通常需要查找相关的表,并根据单个值或一组值提取某些行。
因此,索引与FK有关的任何列是很有意义的,但FK本身并不是索引。
查看Kimberly Tripp的优秀文章“SQL Server何时停止在外键列上放置索引?”
哇,答案五花八门。文档中说:
FOREIGN KEY约束是索引的候选者,因为:
Changes to PRIMARY KEY constraints are checked with FOREIGN KEY constraints in related tables. Foreign key columns are often used in join criteria when the data from related tables is combined in queries by matching the column(s) in the FOREIGN KEY constraint of one table with the primary or unique key column(s) in the other table. An index allows Microsoft® SQL Server™ 2000 to find related data in the foreign key table quickly. However, creating this index is not a requirement. Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
因此,很明显(尽管文档有点混乱),它实际上并没有创建索引。
严格来说,外键与索引毫无关系。但是,正如我上面的演讲者指出的,创建一个加速fk查找是有意义的。事实上,在MySQL中,如果你没有在FK声明中指定索引,引擎(InnoDB)会自动为你创建索引。
假设你有一张大桌子叫订单,一张小桌子叫客户。从订单到客户有一个外键。现在如果你删除一个客户,Sql Server必须检查是否有孤儿订单;如果存在,则会引发一个错误。
为了检查是否有订单,Sql Server必须搜索大订单表。现在如果有索引,搜索就会很快;如果没有,搜索将是缓慢的。
因此,在这种情况下,缓慢的删除可以用缺少索引来解释。特别是如果Sql Server必须在没有索引的情况下搜索15个大表。
附注:如果外键有ON DELETE CASCADE, Sql Server仍然需要搜索订单表,但随后删除引用被删除客户的任何订单。
在PostgeSql中,如果你点击\d tablename,你可以自己检查索引
您将看到,btree索引已经在具有主键和唯一约束的列上自动创建,但没有在具有外键的列上自动创建。
我认为这至少对研究生来说回答了你的问题。
视情况而定。在MySQL中,如果你没有自己创建索引,就会创建索引:
MySQL要求外键列被索引;如果创建的表具有外键约束,但给定列上没有索引,则会创建索引。
来源:https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html
MySQL 5.6也一样。