当前位置:  开发笔记 > 数据库 > 正文

外键是否在SQL Server中自动编入索引?

如何解决《外键是否在SQLServer中自动编入索引?》经验,为你挑选了3个好方法。

以下SQL语句是否会自动在Table1.Table1Column上创建索引,还是必须显式创建索引?

数据库引擎是SQL Server 2000

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

        )

jons911.. 61

SQL Server不会自动在外键上创建索引.也来自MSDN:

FOREIGN KEY约束不必仅链接到另一个表中的PRIMARY KEY约束; 它也可以定义为引用另一个表中UNIQUE约束的列.FOREIGN KEY约束可以包含空值; 但是,如果复合FOREIGN KEY约束的任何列包含空值,则会跳过对构成FOREIGN KEY约束的所有值的验证.要确保验证复合FOREIGN KEY约束的所有值,请在所有参与列上指定NOT NULL.

引用文本与未自动创建索引的问题或语句有什么关系? (6认同)


Charles Bret.. 23

当我读到Mike的问题时,他正在询问FK约束是否会在FK所在的表中的FK列上创建一个索引(表1).答案是否定的,一般而言.(出于约束的目的),不需要这样做.另一方面,定义为约束的"TARGET"的列必须是引用表中的唯一索引,或者是主键或备用钥匙.(唯一索引)或创建约束规则将失败.

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

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



1> jons911..:

SQL Server不会自动在外键上创建索引.也来自MSDN:

FOREIGN KEY约束不必仅链接到另一个表中的PRIMARY KEY约束; 它也可以定义为引用另一个表中UNIQUE约束的列.FOREIGN KEY约束可以包含空值; 但是,如果复合FOREIGN KEY约束的任何列包含空值,则会跳过对构成FOREIGN KEY约束的所有值的验证.要确保验证复合FOREIGN KEY约束的所有值,请在所有参与列上指定NOT NULL.


引用文本与未自动创建索引的问题或语句有什么关系?

2> Charles Bret..:

当我读到Mike的问题时,他正在询问FK约束是否会在FK所在的表中的FK列上创建一个索引(表1).答案是否定的,一般而言.(出于约束的目的),不需要这样做.另一方面,定义为约束的"TARGET"的列必须是引用表中的唯一索引,或者是主键或备用钥匙.(唯一索引)或创建约束规则将失败.

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

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


"而且通常没有必要这样做......" - 这种说法是不正确的我害怕.索引FK可以在许多情况下提高性能.

3> David Sopko..:

不,在列上创建外键不会自动在该列上创建索引.

无法索引外键列将导致在以下每种情况下进行表扫描:每次从引用的(父)表中删除记录时,每次在外键上连接两个表时,每次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

通常,不对索引进行索引比规则更为例外.

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有