我被告知,如果我外键两个表,SQL Server将在子表中创建类似于索引的东西。我很难相信这是真的,但找不到太多与此相关的具体信息。
我问这个问题的真正原因是,对于一个可能有15个相关表的表,我们在delete语句中遇到了一些非常慢的响应时间。我问过我们数据库的人,他说如果字段上有外键,它就像一个索引。你在这方面有什么经验?我是否应该在所有外键字段上添加索引,或者它们只是不必要的开销?
我被告知,如果我外键两个表,SQL Server将在子表中创建类似于索引的东西。我很难相信这是真的,但找不到太多与此相关的具体信息。
我问这个问题的真正原因是,对于一个可能有15个相关表的表,我们在delete语句中遇到了一些非常慢的响应时间。我问过我们数据库的人,他说如果字段上有外键,它就像一个索引。你在这方面有什么经验?我是否应该在所有外键字段上添加索引,或者它们只是不必要的开销?
当前回答
假设你有一张大桌子叫订单,一张小桌子叫客户。从订单到客户有一个外键。现在如果你删除一个客户,Sql Server必须检查是否有孤儿订单;如果存在,则会引发一个错误。
为了检查是否有订单,Sql Server必须搜索大订单表。现在如果有索引,搜索就会很快;如果没有,搜索将是缓慢的。
因此,在这种情况下,缓慢的删除可以用缺少索引来解释。特别是如果Sql Server必须在没有索引的情况下搜索15个大表。
附注:如果外键有ON DELETE CASCADE, Sql Server仍然需要搜索订单表,但随后删除引用被删除客户的任何订单。
其他回答
据我所知没有。外键只添加了一个约束,即子键中的值也要表示在父列中的某个位置。它没有告诉数据库子键也需要被索引,只是被约束。
SQL Server自动为主键创建索引,但不为外键创建索引。为外键创建索引。这可能是值得的。
外键是一种约束,是两个表之间的关系——本质上与索引无关。
但是,索引作为任何外键关系一部分的所有列非常有意义。fk关系通常需要查找相关的表,并根据单个值或一组值提取某些行。
因此,索引与FK有关的任何列是很有意义的,但FK本身并不是索引。
查看Kimberly Tripp的优秀文章“SQL Server何时停止在外键列上放置索引?”
外键不创建索引。只有备用键约束(UNIQUE)和主键约束才能创建索引。这在Oracle和SQL Server中是正确的。
假设你有一张大桌子叫订单,一张小桌子叫客户。从订单到客户有一个外键。现在如果你删除一个客户,Sql Server必须检查是否有孤儿订单;如果存在,则会引发一个错误。
为了检查是否有订单,Sql Server必须搜索大订单表。现在如果有索引,搜索就会很快;如果没有,搜索将是缓慢的。
因此,在这种情况下,缓慢的删除可以用缺少索引来解释。特别是如果Sql Server必须在没有索引的情况下搜索15个大表。
附注:如果外键有ON DELETE CASCADE, Sql Server仍然需要搜索订单表,但随后删除引用被删除客户的任何订单。