两列上的SQL索引

时间:2011-05-24 13:24:50

标签: sql-server indexing

这是我的简单场景:

我有一个Users表和一个Locations表。 一个用户可以与多个地点相关联,因此我有一个UserLocation表,如下所示:

ID (int-Auto Increment) PK
UserID (Int FK to the Users table)
LocID (Int FK to the Locations table)

现在,由于ID是PK,因此它在SQL-Server中默认为索引。我对其他两个专栏感到有点困惑:

  

OPT 1: Shud我在两个列上定义了一个索引,如:   IX_UserLocation_UserID_LocID

     

OR

     

OPT 2: Shud我定义了两个单独的索引,如:IX_UserLocation_UserID   &安培; IX_UserLocation_LocID

请原谅我,如果两者都这样做 - 在这种情况下请解释一下。如果不是 - 哪一个更好,为什么?

5 个答案:

答案 0 :(得分:3)

你需要

  • 2列
    • UserID(Int FK到Users表)
    • LocID(Int FK到Locations表)
  • (UserID, LocID)
  • 上的一个PK
  • 反向(LocID, UserID)
  • 上的另一个索引

您可能不需要两个索引但很少

编辑,指向其他SO答案的一些链接

答案 1 :(得分:2)

我们雇佣数据库有几件事。一种是快速信息检索,另一种是声明性参照完整性(DRI)。

如果您要求用户可能只与给定位置相关,那么您需要UserID&amp ;;的唯一索引。 LocatonID。

如果你的问题是如何快速检索数据答案是 - 这取决于。你是如何访问数据的?如果您始终为用户获取整个位置集,那么我可能会在UserID上使用聚集的非唯一索引。如果你的访问权限是“谁在locatin x?”那么你可能想要一个LocationID上的聚集非唯一索引。

如果你问这两个问题,你可能会想要两个索引(尽管你只有1个聚类,所以第二个索引可能想要使用INCLUDE来获取另一个列)。

无论哪种方式,你probalby不希望ID作为你的聚集索引(在SSMS表设计器中将列标记为PK时的默认值)。

HTH, -eric

答案 2 :(得分:1)

除了“ gbn ”的答案。它取决于 Where 子句。无论您是使用用户还是位置,还是两者都

答案 3 :(得分:0)

设置您认为自己需要的所有索引的最佳方法,然后查看应用运行的查询的query plans,并查看要读取的索引。

答案 4 :(得分:0)

您应该创建两个单独的索引。使用外键经常忘记的一件事是删除用户可能会级联删除表中的用户位置关系。如果userID上没有索引,则可能会导致用户位置关系的表锁定。这同样适用于删除位置。