前言:
在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次DTA,里面提示了很多列缺少统计信息,后来在不改动其他操作的前提下,把这些统计信息手动建上去,性能提升非常明显。关于统计信息将另开文章介绍)。一个表甚至有20多个索引(索引的数量并没有标准,但是要尽量合理,每个索引都应该能支撑大量查询或者增删改中的查询功能才有存在价值)。索引过多带来了服务器的沉重压力,有这么一句话:不合理的索引比没有索引更加惨。可见索引不能随便建。
那如何知道哪些列需要索引?哪些索引可以删除或合并或修改?虽然网上有不少类似文章和方法,但通常比较零散,用起来比较费力。本文结合个人工作经历和网上资料,经过实践,得出一个个人认为行之有效的方法。在后续的工作和学习中,若有改进,将同步修改本文。
注:如非特殊说明,这里说的索引都是非聚集索引。
介绍:
绝大部分人都知道,索引的好处,但是极其少人深刻感受到它的坏处。我一直这么认为,对于SQL Server中的索引(甚至一切数据库管理系统,再甚至世间绝大部分事物)而言,并没有绝对的好或者绝对的坏。就好像给你一把斧头和一个刀片,让你砍一棵树和切割一张纸,你非要用刀片砍树,斧头切纸,然后说刀片和斧头本文来源gaodai#ma#com搞*!代#%^码$网!都是烂东西,显然不合理(这不是段子也不是脑筋急转弯,别纠结太多)。
SQL Server既然提供了一些供你选择的功能,那么就有它的适用场景和不适用场景。用好了,查询能从几个小时提升到几秒,用不好,可以把一个查询从几秒降到几个小时。本文不打算过于深入地讨论索引内部机制,更详细的信息可以翻阅《SQL Server 性能优化与管理的艺术》中第六章的内。这里只是想表达,关于索引:建要建得有理有据。删/合并同样也要有理有据,看到不合适就删,觉得有效果就加,往往只能得到反效果。
所以合理使用索引,本文内容分几部分:
第一部分介绍索引过多的问题;第二部分介绍索引不足的问题;第三部分是索引不合理的问题;最后一部分是对前面三个问题进行实操的方法演示。但是由于本部分篇幅较长,截图较多,为了避免阅读疲劳,所以独立一篇演示。
本篇的初衷如下:可以看到这是个死循环,由于下面的原因导致表上的索引混乱,从而影响整个系统的效率。下面将一一介绍。
3.添加一个覆盖索引,覆盖查询中WHERE条件和SELECT条件的列
--这里为了避免涉及过多内容,对索引首列做了限制,用于满足where条件CREATE NONCLUSTERED INDEX IX_Person_FirstNameON dbo.Person(FirstName,Title,MiddleName,LastName)GO --添加一个覆盖索引,覆盖查询中WHERE条件和SELECT条件的列select Title,FirstName,MiddleName,LastNamefrom dbo.Personwhere FirstName like 'o%'
从下图可见,索引可以覆盖我们的查询:
4.删除上面的索引,添加一个包含索引,但是WHERE条件中的FirstName列只出现在INCLUDE中:
--创建包含索引CREATE NONCLUSTERED INDEX IX_Person_FirstNameON dbo.Person(Title) INCLUDE(FirstName,MiddleName,LastName)GO --删除上面的索引,添加一个包含索引,但是WHERE条件中的FirstName列只出现在INCLUDE中select Title,FirstName,MiddleName,LastNamefrom dbo.Personwhere FirstName like 'o%'
查看执行计划,可以看到走的是索引扫描,因为虽然都是同样的列,但是由于INCLUDE中出现的列通常仅用于协助SELECT而不是协助WHERE,所以没有起到我们期望的作用。
从上面的演示中我们看到,虽然类似,但是如果设计不合理,同样会造成索引问题,读者可以自行测试包含索引中,SELECT的列出现在INCLUDE中,而WHERE的列出现在INCLUDE前的效果,可以看到这次这个包含索引就满足我们的期望了。并且你可以测试,INCLUDE中的列顺序可以和SELECT中的不一致,在本例中不影响效果。
总结:
由于索引是非常大和非常高深的话题,本人读过一本600页的全英的关于SQL Server索引的书籍,密密麻麻的600页却还没有完全解答我的疑问,所以这里我过滤了很多细节问题,把讨论和演示集中在我希望表达的主题上。下一篇文章将演示对这些索引问题的处理手段。
另外需要提醒的是,一个系统的索引问题不可能只有这么三类,但是基于实操出发,把最近个人工作过程中发现的问题整理分享,在后续过程中会不断完善这个话题。广告时间:更多信息可以阅读本人出版的书籍《SQL Server 性能优化与管理的艺术》。
下一篇文章: SQL Server 索引维护(1)——如何获取索引使用情况