索引外键列

时间:2011-03-27 19:43:59

标签: database-design

在所有外键列上放置索引是一条经验法则吗?看起来它们通常会在表连接中使用,并且会从索引中获益。

如果FK列只有2或3个可能值,该怎么办?例如,如果它正在引用状态表。是否仍然建议在FK字段上加上索引?

修改 我想重新提出这个问题。 [建议在具有少量可能值(2或3)的列上放置索引吗?] 结束编辑

3 个答案:

答案 0 :(得分:4)

我强烈反对Eelke - 大多数SQL Server专家建议在外键列上放置非聚集索引,我同意。

有关这些指数的理由和最佳论证的最佳总结,请参阅Kimberly Tripp的优秀博客文章When did SQL Server stop putting indexes on foreign keys? - 答案是:从来没有 - 它从来没有(这是许多持久的都市神话中的一个 - 但它是仍然是一个神话)。

她的核心信息是:

  

索引是否有任何好处   外键列?的

     
      
  • 在维持关系上更好的表现   删除主/唯一密钥。什么时候   删除密钥行,SQL Server必须   检查是否有任何行   它引用了被删除的行   o如果使用NO ACTION定义外键关系   (在更新/删除时)然后引用   行不能被删除   保留引用行“孤立”。   要有效地查找行索引   在外键列上有帮助!
      o如果使用CASCADE定义外键关系   (在更新/删除时)然后当a   引用的行被修改了所有的   引用行必须修改为   好(要么更新以反映   新值或级联删除)。至   找到要有效修改的行,   外键列的索引   帮助!

  •   
  • 更好的连接性能 - 出于上述许多原因,SQL Server   可以更有效地找到行   加入表时加入   主要/外键关系。   然而,这并不总是“最好的”   连接的索引选择,但它是一个   良好的开端。

  •   

答案 1 :(得分:2)

(这里有两个问题:机器效率和DBA效率。)

根据经验,查询性能会受益于JOIN子句和WHERE子句中使用的列的索引。当然,插入,更新和删除性能会受到这些相同索引的影响。 (因为索引必须与表一起更新。)

如果列的值很少,并且有一个令人信服的理由避免在表中存储实际值,我更喜欢人类可读的代码作为外键引用的目标。例如,ISO 5218规定了这些代表人类性别的代码。

Sex_id  Sex
--
0       Not known
1       Male
2       Female
9       Not applicable

我不希望人们记住 9 意味着不适用。如果这就是我所拥有的,那么每当我需要为人们阅读产生输出时,我就必须加入这个表格。

但我可以在该表中添加一列,声明它是唯一的,并将其用作外键引用的目标。我大部分时间都不必加入这张桌子。哎呀,我可能从不必须加入它。避免连接与机器效率有关。

sex_id  sex_code   sex
--
0       Un         Not known
1       M          Male
2       F          Female
9       NA         Not applicable

这三列中的所有列都应声明为唯一。在大多数平台上,这意味着这三列中的每一列都将获得一个索引。即使选择性很低,我也会引用引用sex_code的列。

为什么呢?我有更好的事情要做,而不是重新评估是否添加索引 now ,因为版本中的优化器足够聪明,可以利用它。这与DBA效率有关。

答案 2 :(得分:0)

不,不应该。索引只应在使用时使用。仅当表具有足够的大小(例如至少三个块)时,才使用索引。对于短行,这很容易就是数百行。