SQL Server 2008索引最佳实践

5

我对选择正确索引有一些疑问:

聚集索引

最佳选项是什么?

通常是主键,但如果主键在搜索中未被使用,例如使用CustomerNo来搜索客户,应将聚集索引放在CustomerNo上吗?

使用SchemaBinding的视图

如果有包含索引的视图,我读到这些索引不会被使用,而表上的索引会被使用。

这没什么意义吧?或者我理解错误?使用“NOExpand”强制从视图而不是表读取索引是否会有所不同?

非聚集索引

添加非聚集索引时,将每个可能的列都包括进去是否是一个好习惯,直到达到极限?

非常感谢您的时间。我正在阅读大型数据库,速度是必须的。


1
坦白地说,目前还没有人回答你的问题。如果CustomerNo可以作为主键,并且该列在搜索中最常使用,并且该列在大多数表中是外键,则应将其设置为主键。 ii)其他非主键列,但在搜索中使用的列可以成为非聚集索引。其他非主键列,虽然不用于搜索条件,但在选择查询中使用,可以包含在非聚集索引中。 - KumarHarsh
4个回答

9
聚集索引是指(a)定义表的存储布局的索引(表数据按聚集键物理排序),以及(b)在该表上的每个非聚集索引中用作“行定位器”的索引。

因此,聚集索引应该是:

  • 狭窄的(4字节最理想,8字节可以接受 - 其他任何大小都太大了)
  • 唯一的(如果您不使用唯一的聚集索引,SQL Server将向您的表添加一个4字节的唯一标识符)
  • 静态的(不应更改)
  • 最理想的情况是它应该是递增的
  • 固定的 - 例如,在聚集索引中不要使用大型Varchar(x)

在这些要求中,INT IDENTITY似乎是最合适、最明显的选择。不要使用可变长度列,不要使用多个列(如果可能的话),不要使用GUID(由于其大小和随机性,这是一个非常糟糕的选择)。

如果想了解有关聚集键和聚集索引的更多背景信息,请阅读 Kimberly Tripp 发表的所有内容!她是 SQL Server 中的索引女王 - 她非常懂行!

例如,查看以下博客文章:

总的来说:不要过度索引!太多索引通常比没有更糟糕!
对于非聚集索引:我通常会索引外键列 - 这些索引有助于JOIN和其他操作,并使事情更快。
除此之外:不要在数据库中放置太多索引!每个索引都必须在表上的每个CRUD操作上进行维护!这是开销 - 不要过度索引!
一个包含所有列的表的索引是一个特别糟糕的主意,因为它真的不能用于很多东西 - 但携带了很多管理开销。
运行您的应用程序,进行性能分析 - 查看哪些操作速度较慢,尝试通过向表中添加一些选择性的索引来优化这些操作。

非常感谢您的时间和非常清晰的回答。学到了很多有趣的东西,再次感谢。 - user9969

2
聚集索引
补充一下marc_s的好回答,关于聚集索引的标准INT IDENTITY PK方法有一个例外情况,那就是当你有父子表格时,所有子项经常与父项同时检索。在这种情况下,通过父键将子表格聚集化将减少检索子项时读取的页面数量。例如:
CREATE TABLE Invoice
(
   -- Use the default MS Approach on the parent, viz Clustered by Surrogate PK 
   InvoiceID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
   -- Index Fields here
);


CREATE TABLE InvoiceLineItem
(
   -- Own Surrogate Key
   InvoiceLineItemID INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
   InvoiceID INT NOT NULL FOREIGN KEY REFERENCES Invoice(InvoiceID),
   -- Line Item Fields Here
);

-- But Cluster on the Parent FK
CREATE CLUSTERED INDEX CL_InvoiceLineItem ON InvoiceLineItem(InvoiceID);

非聚集索引
不要轻率地包含列 - 索引树需要尽可能窄。索引列的排序至关重要,始终确保设计索引时考虑到数据的选择性 - 您需要充分了解数据的分布以选择最佳索引。
您可以考虑使用覆盖索引,包括(最多几个)列,否则在调整性能关键查询时需要从非聚集索引返回表中的书签查找。

1
作为一个非常基本的经验法则,当查询返回少量数据时,请使用非聚集索引;当查询返回较大结果集时,请使用聚集索引。
我建议您阅读聚集索引设计指南
至于视图索引:索引视图与索引表相同。它可以提高性能,但像索引表一样,也可能会减慢速度。
我建议您阅读使用SQL Server 2008索引视图提高性能

通常情况下,我发现索引越少越好。你需要研究你的数据,而不是随便在所有东西上添加索引。检查你链接的内容,添加索引并检查执行计划。有时候你认为会成为一个好的索引实际上可能会使事情变得更慢。


0

使用SchemaBinding的视图

...

这有什么意义吗?还是我错过了什么?

(更准确地说,索引视图,schemabinding在这里是达到目的的一种手段,其余的文本更多地讨论了索引视图)

创建索引视图可能有(至少)两个原因。如果没有看到您的数据库,就无法确定哪些原因适用。

第一个原因是计算从基表中计算出来的昂贵的中间结果。为了从该计算中受益,您需要确保查询使用索引。要使用索引,您需要查询视图并指定NOEXPAND,或者使用企业版或开发人员版(在Ent/Dev版本上,即使查询基表且未提及视图,也可能使用索引)

第二个原因是强制执行无法以更简单的方式执行的约束,例如在视图上实现unique约束,这可能会对基表强制执行某种条件唯一性。

第二个示例 - 假设您希望表T能够包含具有相同 U 值的多行数据,但其中只有一行可以标记为 Default。在可用过滤索引之前,通常采用以下方式实现:

CREATE VIEW DRI_T_OneDefault
WITH SCHEMABINDING
AS
    SELECT U
    FROM S.T
    WHERE Default = 1
GO
CREATE UNIQUE CLUSTERED INDEX IX_DRI_T_OneDefault on DRI_T_OneDefault (U)

关键在于这些索引强制执行约束。在这种情况下,任何查询是否实际使用索引都无关紧要。就像可以在基表上声明任何唯一约束,但实际上从未在任何查询中使用一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接