Sql server 外键是否在SQL Server中自动编制索引?

Sql server 外键是否在SQL Server中自动编制索引?,sql-server,indexing,foreign-keys,Sql Server,Indexing,Foreign Keys,下面的SQL语句会自动在Table1.Table1列上创建索引,还是必须显式创建索引 数据库引擎是SQL Server 2000 CREATE TABLE [Table1] ( . . . CONSTRAINT [FK_Table1_Table2] FOREIGN KEY ( [Table1Column] ) REFERENCES [Table2] (

下面的SQL语句会自动在Table1.Table1列上创建索引,还是必须显式创建索引

数据库引擎是SQL Server 2000

       CREATE TABLE [Table1] (
. . .
            CONSTRAINT [FK_Table1_Table2] FOREIGN KEY 
            (
                [Table1Column]
            ) REFERENCES [Table2] (
                [Table2ID]
            )

        )

SQL Server不会自动在外键上创建索引。同样来自MSDN:

外键约束不存在 仅链接到主键 另一个表中的约束;它可以 也可以定义为引用 中唯一约束的列 另一张桌子。外键 约束可以包含空值; 但是,如果组合的任何列 外键约束包含null 值,所有值的验证 组成外键的 跳过约束。确定 所有的价值观都是复合的 验证密钥约束后,指定 在所有参与的 列


当我阅读Mike的问题时,他询问FK约束是否会在FK所在的表(表1)中的FK列上创建索引。答案是否定的,一般来说。(出于约束的目的),不需要这样做。另一方面,定义为约束“目标”的列必须是引用表中的唯一索引,主键或备用键。(唯一索引)或创建约束状态将失败

(编辑:添加以明确处理以下评论-) 具体来说,当提供外键约束所用于的数据一致性时。索引只能在删除FK侧的一行或多行时影响DRI约束的性能。使用约束时,在插入或更新过程中,处理器知道FK值,并且必须检查PK侧引用表中是否存在行。那里已经有索引了。删除PK侧的行时,必须验证FK侧没有行。在这种情况下,索引可能会略有帮助。但这种情况并不常见


除此之外,在某些类型的查询中,查询处理器需要在使用该外键列的联接的多个端上查找记录。当外键上存在索引时,联接性能会提高。但这种情况是在联接查询中使用FK列所特有的,而不是外键约束的存在。。。连接的另一端是PK还是其他任意列并不重要。此外,如果需要根据FK列筛选或排序查询结果,索引将有助于。。。同样,这与该列上的外键约束无关

否,在列上创建外键不会自动在该列上创建索引。在以下每种情况下,未能索引外键列将导致表扫描:

  • 每次从引用(父)表中删除记录时
  • 每次在外键上连接两个表时
  • 每次更新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字段永远不会更新,删除记录几乎永远不会更新,如果CarInventory从未按CarTypeID搜索过,则在CarInventory.CarTypeID上维护索引的服务器开销将是不必要的。

所有证据似乎都表明Table1列上没有自动索引。正常创建索引时,SQL Server不会抱怨。引用的文本与问题或未自动创建索引的语句有什么关系?“通常不需要这样做…”-恐怕该语句不正确。在许多情况下,索引FK可以带来更好的性能。@Mike,您可能希望在联接中使用同一列(索引可能有帮助)这一事实并不意味着约束需要索引。您可能还希望在where子句谓词中使用索引,其中索引也可能有所帮助。这是否意味着仅DRI约束的FK侧需要索引?不,约束上的FK“一般”(PK端的删除除外)不会从索引中获益。在联接(不同情况)或Where子句中使用FK列可以从索引中获益。如果外键上没有索引,则删除引用表上的行将导致使用外键扫描表。如果外键没有索引,简单地连接表将导致表扫描。例如:以“PurchasedItems”和“PurchasedItems”表为例。对于特定的购买,加入PurchasedItems将扫描所有已购买的物品。