在所有外键列上放置索引是一条经验法则吗?看起来它们通常会在表连接中使用,并且会从索引中获益。
如果FK列只有2或3个可能值,该怎么办?例如,如果它正在引用状态表。是否仍然建议在FK字段上加上索引?
修改 我想重新提出这个问题。 [建议在具有少量可能值(2或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)
不,不应该。索引只应在使用时使用。仅当表具有足够的大小(例如至少三个块)时,才使用索引。对于短行,这很容易就是数百行。