以下SQL语句会自动在Table1.Table1Column上创建索引,还是必须显式创建索引?
数据库引擎是SQL Server 2000
CREATE TABLE [Table1] (
. . .
CONSTRAINT [FK_Table1_Table2] FOREIGN KEY
(
[Table1Column]
) REFERENCES [Table2] (
[Table2ID]
)
)
答案 0 :(得分:60)
SQL Server不会自动在外键上创建索引。也来自MSDN:
FOREIGN KEY约束没有 仅链接到PRIMARY KEY 另一个表中的约束;它可以 也可以定义参考 UNIQUE约束的列 另一张桌子。一把外国钥匙 约束可以包含空值; 但是,如果是复合材料的任何列 FOREIGN KEY约束包含null 价值观,所有价值的验证 构成外键的 跳过约束。确保;确定 复合FOREIGN的所有值 验证KEY约束,指定 所有参与者都不是NULL 列。
答案 1 :(得分:23)
当我读到Mike的问题时,他正在询问FK约束是否会在FK所在的表中的FK列上创建索引(表1)。答案是否定的,一般而言。 (出于约束的目的),不需要这样做。另一方面,定义为约束的“TARGET”的列必须是引用表中的唯一索引,或者是主键或备用钥匙。 (唯一索引)或创建约束规则将失败。
(编辑:已添加以明确处理以下评论 - ) 具体而言,在提供外键约束所针对的数据一致性时。索引只会影响FK端行或行的删除,从而影响DRI约束的性能。使用约束时,在插入或更新期间,处理器知道FK值,并且必须检查PK侧上引用表中是否存在行。那里已有一个索引。删除PK端的行时,必须验证FK端没有行。在这种情况下,索引可能略有帮助。但这不是常见的情况。
除此之外,在某些类型的查询中,查询处理器需要在使用该外键列的连接的多个边上查找记录。当该外键上存在索引时,连接性能 增加。但是这种情况在连接查询中使用FK列是特殊的,而不是外键约束的存在......连接的另一侧是PK还是其他任意列并不重要。此外,如果您需要过滤或根据该FK列对查询结果进行排序,索引将有所帮助......同样,这与该列上的外键约束无关。
答案 2 :(得分:6)
不,在列上创建外键不会自动在该列上创建索引。未能索引外键列将导致在以下每种情况下进行表扫描:
在此示例模式中:
CREATE TABLE MasterOrder (
MasterOrderID INT PRIMARY KEY)
CREATE TABLE OrderDetail(
OrderDetailID INT,
MasterOrderID INT FOREIGN KEY REFERENCES MasterOrder(MasterOrderID)
)
每次在MasterOrder表中删除记录时,都会扫描OrderDetail。每次加入OrderMaster和OrderDetail时,也会扫描整个OrderDetail表。
SELECT ..
FROM
MasterOrder ord
LEFT JOIN OrderDetail det
ON det.MasterOrderID = ord.MasterOrderID
WHERE ord.OrderMasterID = @OrderMasterID
一般情况下,不对索引编制索引比规则更为例外。
不索引外键的情况是永远不会被利用的地方。这将使服务器维护它不必要的开销。类型表可能会不时属于此类别,例如:
CREATE TABLE CarType (
CarTypeID INT PRIMARY KEY,
CarTypeName VARCHAR(25)
)
INSERT CarType .. VALUES(1,'SEDAN')
INSERT CarType .. VALUES(2,'COUP')
INSERT CarType .. VALUES(3,'CONVERTABLE')
CREATE TABLE CarInventory (
CarInventoryID INT,
CarTypeID INT FOREIGN KEY REFERENCES CarType(CarTypeID)
)
假设CarType.CarTypeID字段永远不会被更新并且删除记录的一般假设几乎不会,如果从未通过CarTypeID搜索CarInventory,则不需要维护CarInventory.CarTypeID上的索引的服务器开销。 / p>