通常是的 - 您通常会在主键上创建聚集索引。例外情况是您从不基于主键进行查找,在这种情况下,将聚集索引放在另一列上可能更相关。
您通常应该向用作外键的列添加非聚集索引,前提是该列具有合理数量的多样性,我将通过一个示例进行解释。
这同样适用于 where 子句、order by 等中使用的列。
例子
CREATE TABLE Gender (
GenderId INT NOT NULL PRIMARY KEY CLUSTERED
Value NVARCHAR(50) NOT NULL)
INSERT Gender(Id, Value) VALUES (1, 'Male'), (2, 'Female')
CREATE TABLE Person (
PersonId INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
Name NVARCHAR(50) NOT NULL,
GenderId INT NOT NULL FOREIGN KEY REFERENCES Gender(GenderId)
)
CREATE TABLE Order (
OrderId INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
OrderDate DATETIME NOT NULL DEFAULT GETDATE(),
OrderTotal DECIMAL(14,2) NOT NULL,
OrderedByPersonId INT NOT NULL FOREIGN KEY REFERENCES Person(PersonId)
)
在这组简单的表中,最好在 Order 表的 OrderedByPersonId 列上放置一个索引,因为您很可能想要检索给定人员的所有订单,并且它可能具有很高的多样性的数量。高度多样性(或选择性)我的意思是,如果您有 1000 个客户,则每个客户可能只有 1 或 2 个订单,因此使用给定的 OrderedByPersonId 从订单表中查找所有值将导致仅返回该表中总记录的一小部分。
相比之下,在 Person 表的 GenderId 列上放置索引没有多大意义,因为它的多样性非常低。查询优化器不会使用这样的索引,并且 INSERT/UPDATE 语句会稍微慢一些,因为需要额外维护索引。
现在回到你的例子 - 答案必须是“它取决于”。如果您的数据库中有数百个城市,那么是的,索引该列可能是个好主意但是如果您只有 3 或 4 个城市,那么不 - 不要打扰。作为准则,我可能会说如果列的选择性为 0.9 或更高(即,在列中选择单个值的 where 子句将导致仅返回 10% 或更少的行),索引可能会有所帮助,但这是绝不是一成不变的人物!
即使该列是非常有选择性/多样化的,如果查询只是非常不频繁地在其上进行,您可能不会费心为其编制索引。
最简单的事情之一是尝试使用 SQL 管理工作室中显示的执行计划进行查询。如果查询优化器认为索引会产生积极影响,它将为您建议索引。
希望有帮助!