如何提高聚簇索引的性能

Abe*_*ler 32 sql sql-server query-performance sql-execution-plan

我正在尝试提高运行速度非常慢的查询的性能.完成实际执行计划后 ; 我发现Clustered Index Seek占82%.有什么方法可以改善Index Seek的表现吗?下面是执行计划中的问题索引查找的图像以及它正在使用的索引和表.

替代文字http://img340.imageshack.us/img340/1346/seek.png

指数:

/****** Object:  Index [IX_Stu]    Script Date: 12/28/2009 11:11:43 ******/
CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
(
 [StuKey] ASC
)WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

表(为简洁起见省略了一些列):

CREATE TABLE [dbo].[stu](
 [StuCertKey] [int] IDENTITY(1,1) NOT NULL,
 [StuKey] [int] NULL
 CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
(
 [StuCertKey] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

Aar*_*ght 21

我在这里概括,但......

在大多数情况下,聚簇索引查找是最佳情况.我能想到提高绩效的唯一方法是:

  • 如果可能,更新查询以返回更少的行/列;
  • 对索引进行碎片整理或重建;
  • 跨多个磁盘/服务器对索引进行分区.

如果它只返回138行,那就慢......也许它被其他一些进程阻止了?您是单独测试这个,还是同时在线测试其他用户/进程?或者它甚至可能是硬件问题,例如磁盘故障.


Str*_*DBA 13

当使用非聚集索引并且不一定是坏的时,会发生聚簇索引.

请考虑以下查询:

SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX'
Run Code Online (Sandbox Code Playgroud)

如果StuKey上只有一个聚簇索引,那么Sql Server只有1个选项,它必须扫描整个表,查找State ="TX"的行并返回这些行.

如果在State上添加非聚集索引

CREATE INDEX IX_Stu_State on Stu (State)
Run Code Online (Sandbox Code Playgroud)

现在Sql server有了一个新选项.它可以选择使用非聚集索引进行搜索,这将产生State ='TX'的行.但是,为了在SELECT中返回剩余的列,它必须通过对每一行执行聚簇索引查找来查找这些列.

如果您想减少聚集索引搜索,那么您可以通过在其中包含额外的列来使您的索引"覆盖".

 CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city )
Run Code Online (Sandbox Code Playgroud)

此索引现在包含回答上述查询所需的所有列.查询将执行索引查找仅返回State ='TX'的行,并且可以从非聚集索引中拉出其他列,因此聚簇索引搜索将消失.


Rem*_*anu 8

一个聚簇索引范围搜索返回138行不是你的问题.

从技术上讲,您可以通过使聚簇索引更窄来提高搜索性能:

两者都可以对范围寻找时间产生相当大的影响,因为它们减少了IO并且需要进行物理读取.当然,通常情况下,结果会因许多其他因素而异,例如您投影的列(将预计列驱逐到BLOB分配单元实际上可能会对某些查询产生负面影响).作为旁注,通常碎片对这种短程扫描只会产生微不足道的影响.再次,这取决于.

但正如我所说,我高度怀疑这是你真正的问题.您只发布了计划的选定部分和您自己的分析结果.真正的根本原因可能完全在其他地方.