有人告诉我,如果我对两个表进行外键调用,则该SQL Server将在子表中创建类似于索引的内容。我很难相信这是真的,但是在这方面找不到很多相关的东西。
我问这个的真正原因是因为我们在一个可能包含15个相关表的表的delete语句中,响应时间很慢。我问过我们的数据库专家,他说如果字段上有外键,那么它就像一个索引。您对此有何经验?我应该在所有外键字段上添加索引还是仅仅是不必要的开销?
有人告诉我,如果我对两个表进行外键调用,则该SQL Server将在子表中创建类似于索引的内容。我很难相信这是真的,但是在这方面找不到很多相关的东西。
我问这个的真正原因是因为我们在一个可能包含15个相关表的表的delete语句中,响应时间很慢。我问过我们的数据库专家,他说如果字段上有外键,那么它就像一个索引。您对此有何经验?我应该在所有外键字段上添加索引还是仅仅是不必要的开销?
Answers:
外键是一个约束,是两个表之间的关系-与索引本身无关。
但是众所周知的事实是,索引属于任何外键关系的所有列都是很有意义的,因为通过FK关系,您通常需要查找相关表并根据以下内容提取某些行:一个值或一个值范围。
因此,对FK中涉及的任何列建立索引是很有意义的,但是FK本身不是索引。
请查看Kimberly Tripp的精彩文章“ SQL Server何时停止在外键列上放置索引?” 。
REFERENCES
。它会自动UNIQUE
为PRIMARY KEY
或UNIQUE
约束创建一个索引,并要求在外键关系的UNIQUE
被引用端存在一个索引,但是对于引用端却没有自动执行任何操作,尽管使自己成为一个好主意。见 stackoverflow.com/questions/970562/...
哇,答案遍及整个地图。因此,文档说:
FOREIGN KEY约束是索引的候选对象,因为:
使用相关表中的FOREIGN KEY约束检查对PRIMARY KEY约束的更改。
通过将一个表的FOREIGN KEY约束中的列与另一表中的主键或唯一键列相匹配,在查询中合并来自相关表的数据时,通常在联接条件中使用外键列。索引使Microsoft®SQL Server™2000可以在外键表中快速找到相关数据。但是,创建此索引不是必需的。即使在表之间未定义PRIMARY KEY或FOREIGN KEY约束,也可以合并来自两个相关表的数据,但是两个表之间的外键关系表明这两个表已经过优化,可以在将键用作它的标准。
因此,很显然(尽管文档有些混乱)它实际上并没有创建索引。
不,外键字段上没有隐式索引,否则Microsoft为什么会说“在外键上创建索引通常很有用”。您的同事可能会将引用表中的外键字段与引用表中的主键混淆了-主键确实会创建隐式索引。
假设您有一个称为“订单”的大表和一个名为“客户”的小表。从订单到客户都有一个外键。现在,如果删除客户,则Sql Server必须检查是否没有孤立订单;否则,SQL Server必须检查是否有孤立订单。如果存在,则会引发错误。
若要检查是否有任何订单,Sql Server必须搜索大订单表。现在,如果有索引,搜索将很快。如果没有,搜索将很慢。
因此,在这种情况下,缓慢删除可以通过缺少索引来解释。尤其是如果Sql Server必须搜索没有索引的15个大表。
PS如果外键具有ON DELETE CASCADE,则Sql Server仍必须搜索订单表,但随后要删除所有引用已删除客户的订单。
外键不创建索引。仅备用键约束(UNIQUE)和主键约束创建索引。在Oracle和SQL Server中都是如此。
我注意到,指向MSSQL的Entity Framework 6.1会自动在外键上添加索引。