0

所以我想知道我是否应该将非聚集索引添加到 SQL 2008 R2 表中的非唯一值列。简化示例:

 SELECT Id, FirstName, LastName, City
 FROM Customers
 WHERE City = 'MyCity'

我的理解是主键[Id]应该是聚集索引。

可以将非聚集索引添加到非唯一列 [City] 吗?这会提高性能还是我根本不应该打扰。

谢谢。

我正在考虑将聚集索引作为:

 CREATE UNIQUE CLUSTERED INDEX IDX_Customers_City 
  ON Customers (City, Id);

或非聚集,假设该表上已经有聚集索引。

  CREATE NONCLUSTERED INDEX IX_Customers_City 
  ON Customers (City, Id);

实际上,我正在处理数百万个记录表。Select 语句返回 0.1% 到 5% 的记录

4

2 回答 2

2

通常是的 - 您通常会在主键上创建聚集索引。例外情况是您从不基于主键进行查找,在这种情况下,将聚集索引放在另一列上可能更相关。

您通常应该向用作外键的列添加非聚集索引,前提是该列具有合理数量的多样性,我将通过一个示例进行解释。

这同样适用于 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 管理工作室中显示的执行计划进行查询。如果查询优化器认为索引会产生积极影响,它将为您建议索引。

希望有帮助!

于 2013-11-06T15:25:41.030 回答
1

如果您经常使用该查询,或者如果您在在线应用程序中定期按城市排序,特别是如果您的表密集或具有较大的行大小,则添加索引是有意义的。太多的索引会减慢您的插入和更新速度。只有当您在表中有重要数据时,才会赞赏对实际值的评估。

于 2013-11-06T14:56:44.407 回答