我一直在我们的MS SQL数据库上运行自动索引工具(我修改了源自Microsoft的脚本,该脚本查看索引统计表-自动自动索引)。从统计信息中,我现在有了需要创建索引的建议列表。

编辑:上述索引从DMV中获取信息,这些信息告诉您如果数据库引擎将索引用于数据库引擎

(上面的部分编辑摘录自以下Larry Coleman的回答,以阐明脚本的内容)。在做)

由于我是数据库管理员的新手,并且已经在网上进行了快速搜索,所以我不愿冒险尝试并盲目添加推荐的索引。但是,由于没有该领域的经验,我正在寻找有关如何确定建议是否必要的建议。

我是否需要运行SQL事件探查器,还是最好检查一下查询表的代码?还有其他建议吗?

评论

看看这篇文章sqlserverperformance.wordpress.com/2007/11/29/…

检查不可用的索引。本文可能会帮助您:sqlshack.com/…

#1 楼

我使用Jason Strate的索引分析脚本(旧位置)。它们告诉您现有索引的使用量以及遗失索引的使用量。我通常不添加索引,除非它们占表查询的5%或10%以上。

最重要的是,它是关于确保应用程序对用户足够快的响应。 br />
双重更新:最近,我在执行索引分析时使用sp_BlitzIndex®。

评论


我们需要对所有表进行哪些更改?

–MonsterMMORPG
16年8月18日在9:34

sp_BlitzIndex将查看所有超过一定大小的表。您必须去看文档以了解如何调整它。

–耶利米·佩斯卡(Jeremiah Peschka)
16年8月18日在12:57

执行sp_BlitzIndex的参数在此处:brentozar.com/blitzindex

–JackArbiter
17年1月31日15:57



任何三重更新?

–Simon_Weaver
18 Mar 10 '18 at 4:12

#2 楼

在处理索引时,需要理解一些重要的概念和术语。搜索,扫描和查找是通过select语句使用索引的一些方式。键列的选择性对于确定索引的有效性必不可少。

当SQL Server查询优化器确定查找所需数据的最佳方法是扫描范围内的一个范围时,就会发生查找。索引。当查询被索引“覆盖”时,通常会发生搜索,这意味着搜索谓词在索引键中,而显示的列在键中或被包含。当SQL Server查询优化器确定查找数据的最佳方法是扫描整个索引,然后过滤结果时,即发生扫描。当索引未在索引键或包含的列中不包括所有请求的列时,通常会发生查找。然后查询优化器将使用聚簇键(针对聚簇索引)或RID(针对堆)“查找”其他请求的列。

通常,查找操作比扫描更有效。 ,因为实际查询的是较小的数据集。在某些情况下不是这样,例如很小的初始数据集,但是超出了您的问题范围。

现在,您问如何确定索引的有效性,还有几件事要牢记。聚簇索引的键列称为聚簇键。这就是在聚集索引的上下文中使记录唯一的方式。默认情况下,所有非聚集索引都将包含聚集键,以便在必要时执行查找。对于每个相应的DML语句,所有索引都将插入,更新或删除。话虽这么说,最好是在选择语句中的性能提升与插入,删除和更新语句中的性能影响之间取得平衡。

为了确定索引的有效性,必须确定索引键的选择性。选择性可以定义为不同记录占总记录的百分比。如果我有一个具有100条记录的[人]表,并且[first_name]列包含90个不同的值,则可以说[first_name]列具有90%的选择性。选择性越高,索引键越有效。牢记选择性,最好将最有选择性的列放在索引键中。使用我以前的[person]示例,如果我们的[last_name]列具有95%的选择性怎么办?我们想创建一个以[last_name],[first_name]作为索引键的索引。确定索引的有效性,并且必须权衡许多性能提升因素。

评论


我只想强调上面所说的内容:索引会使您的插入/删除和更新速度变慢。如果不得不说要批量插入大量数据,那么最好不用索引(可以在以后创建索引,这样更快)。

–尼古拉斯·德·丰特奈(Nicolas de Fontenay)
2011年4月21日在10:28

提到[last_name],[first_name]列上的索引仅在查询将根据last_name和first_name进行筛选时才可以使用吗?如果仅对first_name进行过滤,则无法使用索引,可以吗?

–魔术师
16年1月13日在9:56

好的答案-在决定是否建立索引时,选择性比基数更重要

–反向工程师
17年5月22日在16:00

#3 楼

我最近从BrentOzar Unltd的人们那里发现了一个很棒的免费脚本
http://www.brentozar.com/blitzindex/

这很好地分析了哪些索引存在,多久使用一次它们的使用以及查询引擎查找不存在的索引的频率。

它的指导通常很好。有时,它会过分暗示建议。到目前为止,我通常已执行以下操作:


删除从未读取过的索引(或每月读取少于50次)。
添加了最明显的外来索引我知道我们经常使用键和字段。

我还没有添加所有推荐的索引,一周后又回过头来发现不再推荐使用它们,因为查询引擎正在使用一些

通常应该避免使用以下索引:


非常小的表(少于50至200条记录):通常是查询引擎如果它扫描表而不是加载索引,进行读取,处理等等,则速度更快。
避免在低基数(http://en.wikipedia.org/wiki/Cardinality_(SQL_statements))的列上建立索引第一个提到的专栏。例如。索引性别字段(M / F)的用处很小,扫描表格并找到匹配的〜50%的内容实际上是一样的。如果将其列在索引中更具体的内容(例如[出生日期,性别])之后,则更好-您可能希望所有在指定时间段内出生的男性。

聚集索引是好的-通常,这些基于您的主键。它们帮助数据库引擎将数据良好地放置在磁盘上。对于最大的表来说,理解这一点非常重要,因为一个好的聚簇索引通常会减少表所占用的空间。

我已经将某些表从900MB减少到了400MB,只是因为它们事先是非结构化堆。
http://msdn.microsoft.com/zh-cn/library/aa933131(v=sql.80).aspx

重组/重建

您应该寻找碎片索引。有点碎片是可以的,不要沉迷! http://technet.microsoft.com/zh-cn/library/ms189858.aspx知道重新组织和重新构建之间的区别!

定期查看

查询更改,数据量更改,添加了新功能,删除了旧功能。您应该每月查看一次(如果数量很大,则应更频繁地查看),并寻找可以在哪里帮助数据库的地方!

有多少个

最近的视频Brent建议(通常)在一个有很多书写的表(例如,订单表)上不要再包含5个索引,如果读取的内容多于书面的(即用于分析的日志记录表),则不超过10个索引。 .youtube.com / watch?v = gOsflkQkHjg

总体

要看情况!

您的里程根据数据库而有所不同。在您的(现在/将来)较大的表上覆盖明显的(员工姓氏,订单日期等)。监视,检查和根据需要进行调整。在管理数据库时,它应该成为例行检查清单的一部分:)

希望有帮助!

#4 楼

通常情况下,需要特定的工作负载(查询)并仔细测试每个新索引对工作负载的影响。该迭代过程应始终包括对执行计划的仔细分析,以揭示所使用的索引。分析查询的主题很长,从MSDN专门的章节“分析查询”开始是一个不错的选择。一个使用数据库引擎优化顾问,该引擎对您的工作量进行一些自动分析并提出一些索引。当然,应仔细分析建议,并应立即评估影响。

因此,如果您遵循我的想法,添加索引并衡量影响实际上只是A / B测试的一种情况:您不使用索引作为基线来运行工作负载,然后运行将其与指标进行比较,衡量并与基准进行比较,然后根据观察和衡量的指标来确定影响是否有益。工作负载最好是高质量的测试套件,但是它也可以是捕获的工作负载的重播,请参阅如何:重播跟踪文件。

更综合的答案是看看sys.dm_db_index_usage_stats视图并了解如何利用索引,但这通常是一种在未知工作负载上进行现场分析的方法(即,可能需要一位咨询专家帮助)。

#5 楼

从SQL 2005开始,SQL Server具有DMV,可以告诉您数据库引擎在索引可用时将使用什么。这些视图可以告诉您哪些列应该是键列,应该包括哪些列,最重要的是,可以使用索引多少次。

一种好的方法是按查找次数对丢失的索引查询进行排序,并考虑先添加顶部索引。

另请参见:官方MS DMV文档

#6 楼

这取决于该表的使用方式。例如可以说我有一个被读取很多次的表,但是很少进行更新和插入。另外,我总是在某些外键列上查询表。在该外键上创建(非聚簇的)索引以加速读取查询将是有意义的。但是不利的是,您的插入,更新将变得缓慢。

很少有统计查询可以告诉您查询花费了多少时间。从最慢的开始。如果查询谓词没有索引,则创建索引将有所帮助。