关闭

SQL Server查询性能优化之创建合理的索引(下)

发表于:2012-7-06 09:44

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:懒惰的肥兔    来源:51Testing软件测试网采编

  可以看到现在索引3也可以有效的用于查询4了,但是由于先导列原因若将Status列和UserID列换货,固然可以提高查询4效率但是会影响查询1,我们考虑到Status列一般也就几种状态,多了也就几十种,相对于UserID来说选择性低高,因此还是把选择性较高的UserID列放在前面,最大化查询1和查询3查询效率。再来看最后一个索引4,索引4和对查询1和查询4起效果,由于查询1已有索引3可用,故忽略对查询1的作用,现在只剩下对查询4的起作用,我们看查询4,索引3和索引4都对其产生效果,毫无疑问索引4对查询4效果更大一些,但考虑到Status列的低选择性和多维护一个索引的代价,索引3已能较好的完成查询4,所以删除索引4。

  这样一来针对Orders表的4个查询,我们经过对原来4个索引的优化调整后只保留了修改后的索引3,索引从4个变成一个,而查询效率方面却没有受较大的影响,达到了用尽可能少的索引完成尽可能多的查询的目的。

  在上面的演示中我们使用了OrderCode做为聚集索引,通过对非聚集索引的调整较好的完成了查询,在大说数情况下这样就可以ok了,现在我们考虑下若Orders表数据量较大,执行我们的查询4若返回结果达到几万、几十万甚至更多的时候,很可能会导致索引失效从而发生表扫描,这时除非我们队查询4使用的索引实现索引覆盖,不过这基本上不大现实。那如何解决这个问题呢?这时时间列上的聚集索引就开始显示威力了,修改我们的Orders表将聚集索引建立到PostTime列上

--删除原来的聚集索引主键 PK_Orders
ALTER TABLE dbo.Orders DROP CONSTRAINT PK_Orders

--创建非聚集索引主键 PK_Orders
ALTER TABLE dbo.Orders ADD CONSTRAINT PK_Orders PRIMARY KEY NONCLUSTERED(OrderCode)

--在时间列PostTime上创建聚集索引
CREATE CLUSTERED INDEX IX_PostTime ON dbo.Orders(PostTime)

  修改后我们担心的书签查找问题彻底消失了,因为通常导致索引失效的原因都是过多的书签查找,发生大量书签查找时基本上和范围查询脱不开关系,大范围数据查询又肯定会用到时间列,所以推荐时间列做聚集索引。至于说修改了聚集索引后更新,订单查询效率会不会下降,对于这点基本上可以忽略,进行订单查询时一般数据量都会较小,那点书签查找开销完全可以忽略掉,比如我们的查询2。

  这时我们可能发现我们上面修改的索引3有个尴尬的现状,索引3的先导列PostTime现在成了聚集索引,那么索引3对查询1、查询3、查询4还有木有用,索引3还有木有存在的必要,关于这点一般来说呢非聚集索引最好不要用聚集索引做先导列,很可能建了等于白建这里只是个建议,那么若删除了索引3,查询1、查询3、查询4效率会如何,查询4效率肯定是会提升的、查询1、查询3需要实际测试,当然若可以的话把聚集索引建成联合的,把UserID放进去就不会有此问题了

--在时间列PostTime和UserID列上创建聚集索引
CREATE CLUSTERED INDEX IX_PostTimeUserID ON dbo.Orders(PostTime,UserID)

  当然了这种修改还得小心进行,根据实际需求灵活修改,理想的情况下是建立专门的只读数据库复制,在只读库上建立最适合范围查找的聚集索引,在主库上建立最有利于增、删、改的聚集索引,对实时性要求不高的查询全部转移到只读库上执行,相对而言需要大范围数据筛选的查询都不需要多好的实时性,尽可到只读库执行,而主库呢肯定是主要执行实时性要求高的小数据量查询。

  总结:

  聚集索引的优势在于大范围数据查询效率,因此需要将聚集索引建立在时间列、选择性相对较低并且经常会用于范围查询的列(选择性过低的如性别列肯定不行,过低的选择性列索引建了等于白建,比如你在性别列上集索引以为通过性别列起码一下过滤掉一半数据,范围大大减小你就大错特错了,这点选择性通常查询优化器会直接忽略掉,还不如个表扫描来的快),充分发挥聚集索引大范围数据查询优势。

  非聚集索引要尽量使用选择性较高的列以尽可能减少返回的数据量,利用组合索引提高索引的复用率,不要建过多的无用索引,如果发现某个表建了很多的非聚集索引,不妨把那些索引、查询摘出来分析合并下,减少没用索引的数量,以提高整体性能。

  索引建立还需根据实际需要进行选择,本文所述观点在能够适用于大多数情况,但建立好的索引不是一朝一夕能够做到的,理论上成立的事实际应用中往往会事与愿违,索引的有效性还要依靠数据库统计信息等综合考虑,故每当建立索引后一定要查看下查询计划,查看下IO开销,看看查询优化器是否按照我们预期的方式使用了索引。

33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号