所以我想知道是否应该将非聚集索引添加到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%
答案 0 :(得分:2)
通常是 - 您通常会在主键上创建聚簇索引。 例外情况是,您从不基于主键进行查找,在这种情况下,将聚簇索引放在另一列上可能更相关。
您通常应该将非聚集索引添加到用作外键的列,前提是该列上存在相当多的多样性,我将通过示例进行解释。
这同样适用于where子句中使用的列,等等。
实施例
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管理工作室中显示的执行计划。如果查询优化器认为它们会产生积极影响,它会为您建议索引。
希望有所帮助!
答案 1 :(得分:1)
如果您经常使用查询,或者如果您在线应用程序中定期按城市排序,特别是如果您的表密集或行数较大,则添加索引是有意义的。索引太多会降低插入和更新的速度。只有在表中包含重要数据时,才能理解对实际值的评估。