热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

SqlServer索引自动优化工具

前段接手了个优化项目,大概要求是对公司现有的1W多张表进行索引优化,完善现有的,剔除无效的索引

前段接手了个优化项目,大概要求是对公司现有的1W多张表进行索引优化,完善现有的,剔除无效的索引

鉴于人手严重不足(当时算两个半人的资源),打消了逐个库手动去改的念头。当前的程序结构不允许搞革命的做法,只能搞搞改良,所以准备搞个自动化工具去处理。原型刚开发完,开会的时候以拿出来就遭到运维DBA团队强烈抵制,具体原因不详。最后无限延期。这里把思路分享下。欢迎拍砖。

  整个思路是这样的,索引都是为查询和更新服务的,但是不合适的索引又会对插入和更新带来负面影响。面对表上现有的索引想识别那些是有效的不太可能。那么根据现有的数据使用情况重建所有的新索引不就解决了嘛。根据查询生成全新索引,然后和现有对比,不吻合的全部删除,原来没有的创建。虽然说对于正在运行的系统来说风险还是蛮大的。但是可以做临界测试嘛。
  
具体解决方案如下:

  首先在热备的数据库服务器上定期抓取缓存的执行计划(原本想抓取SQL发现有些SQL实在掺不忍睹,没有自动化解析的可能性),然后连同该执行的执行次数即表的统计信息一起down到一个备用服务器的数据表中。

  执行计划积累几次后,开始解析。由于执行计划是格式良好的XML文件,加上微软提供执行计划的XSD文件。我们可以反向推出各节点对应的SQL谓词(这个XSD到现在都没找到官方的说明,只能反向推出关联)。例如建立索引我们比较关心三类谓词,分别为:Select,Join,Where。 只要拿到这些我们就能建立良好的索引。原理很简单,Join和Where都是索引键的依据,而Select可以斟请添加到Index的Include中。
  
  解析的时候也不是针对单个执行计划,而是将所有执行计划全分解后进行统计处理。好处就是能够知道那些表字段被引用的最多,那些是外键列。那些数据被反复查询。例如可以得出TableA的Col1列在一天的业务过程中被Join了10W次,被Where2W次。而Col2则被Select了10W次,仅仅被Where了100次。这样我们建立索引的基础就是基于表的而不是基于单个查询的。最终生成的Index将权衡查询频率和查询的重要性,如果某个业务查询特别重要,但执行频率不高我们可以提供权重,优先建立索引。当然创建Index还要参考表的数据分布以决定Index中字段的顺序。

  好了,准备工作完成,开始建索引。当前拥有的条件,表数据分布,表字段分别被查询引用次数(Select,Join,Where),以及这些SQL谓词出现的次数。根据这些如何创建索引开始的想法是逐个分析,考虑所有可能性然后创建。发现这种方式只适合人脑,让电脑做得先让电脑的智商增长到120以上才有可行性。发现逆向思维这里同样大有用处,既然不能一下子创建最合适的,那我们就根据执行计划得出的组合创建所有的Index组合。凡是Join和Where都放到Index的Key里。例如:
  select t1.A, t1.B, t1.C, t2.J, t2.k from Table1 t1 Join Table1 t2 on t1.A = t2.j Where t1.A = 'param'

草创的索引就是:

  Index(A,B)includ(C) 和 Index(j)include(j,k)

关于Select如果是小数据类型且Alter的执行计划中该数据修改频率很小的都放到Include里去进去。大数据类型和修改比较频繁的就算了。这样我们剔除相互覆盖的。部分重叠的,部分重叠到底保留那一个参考执行频率和查询重要性。差异很小的就合并并为一个,如:

  1.Index (A,B,C)Include(D)
  2.Index(A,B,D)Include(C)

直接合并为:

  Index(A,B)Include(C,D)

当然如果Alert的特别少也可以合并成Index(A,B,C,D)这个要参考C,D字段的修改频率。和主键重叠的剔除。这样留下的基本上就是我们需要的索引了。
  
  对比现有索引进行甄别覆盖的过程就略过。简单的拉出来Create Index 进行解析处理就好了。发布的时候很简单。写个脚本在业务比较少的时候做Drop和Create就完成了。项目源代码因为设计到公司的保密问题就不上传了。一个注意的地方对于简单查询的SQL执行计划缓存的时候会比较短且一旦缓存不够就会被清理掉。要注意这些SQL的执行频率的误差。

  SqlserverR2 XSD:
 
 总结的节点映射列举如下:

    查询sql执行计划都包含在节点“StmtSimple”中,如果没有这个节点一般就是其它类型的SQL的执行计划。

    Join关联的节点和自身类型有关一般包含在Hash,Marger中,如何Join同时又是Where条件的话则会出现在SeekKey和Compare节点中,因为Join的列都是成对出现,这里很容易识别,有一个是参数(@开头)或常量(type="Const")则必定是Where条件。
    
    Select最终输出字段比较容易找到,第一个OutputList节点就是。

    需要注意的是有因为一般列每个ColumnReference都包含库名,表名,列信息,但是系统表则不会。注意剔除。
推荐阅读
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文探讨了 RESTful API 和传统接口之间的关键差异,解释了为什么 RESTful API 在设计和实现上具有独特的优势。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 精选30本C# ASP.NET SQL中文PDF电子书合集
    欢迎订阅我们的技术博客,获取更多关于C#、ASP.NET和SQL的最新资讯和资源。 ... [详细]
author-avatar
evon0207165
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有