不,在列上创建外键不会自动在该列上创建索引。未能索引外键列将在以下每种情况下导致表扫描:
- 每次从引用(父)表中删除一条记录。
- 每次这两个表在外键上连接。
- 每次更新 FK 列。
在此示例架构中:
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 上的索引的服务器开销将是不必要的。