SqlServer 索引自动优化工具
前段接手了个优化项目,大概要求是对公司现有的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都包含库名,表名,列信息,但是系统表则不会。注意剔除。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

如何在Window11上修复100%的磁盘使用率查找导致100%磁盘使用的有问题的应用程序或服务的直接方法是使用任务管理器。要打开任务管理器,请右键单击开始菜单并选择任务管理器。单击磁盘列标题,查看占用最多资源的内容。从那里开始,您将很好地了解从哪里开始。但是,问题可能比仅仅关闭应用程序或禁用服务更严重。继续阅读以查找问题的更多潜在原因以及如何解决这些问题。禁用SuperfetchSuperfetch功能(在Windows11中也称为SysMain)有助于通过访问预取文件来减少启动时

如何在Windows11上从搜索中隐藏文件和文件夹我们首先要看的是自定义Windows搜索文件的位置。通过跳过这些特定位置,您应该可以更快地看到结果,同时还可以隐藏您想要保护的任何文件。如果要从Windows11上的搜索中排除文件和文件夹,请使用以下步骤:

如果您的搜索栏在Windows11中不起作用,有几种快速方法可以立即启动并运行!任何微软操作系统有时都可能遇到故障,最新的操作系统不能免除该规则。此外,正如Reddit上的用户u/zebra_head1所指出的那样,同样的错误出现在Windows11的22H2Build22621.1413上。用户抱怨切换任务栏搜索框的选项随机消失。因此,您必须为任何情况做好准备。为什么我无法在计算机上的搜索栏中键入内容?无法在计算机上键入可归因于不同的因素和过程。以下是您应该注意的一些事项:Ctfmon.

oracle索引类型有:1、B-Tree索引;2、位图索引;3、函数索引;4、哈希索引;5、反向键索引;6、局部索引;7、全局索引;8、域索引;9、位图连接索引;10、复合索引。详细介绍:1、B-Tree索引,是一种自平衡的、可以高效地支持并发操作的树形数据结构,在Oracle数据库中,B-Tree索引是最常用的一种索引类型;2、位图索引,是一种基于位图算法的索引类型等等。

在Outlook中运行搜索和索引疑难解答您可以开始的更直接的修复之一是运行搜索和索引疑难解答。要在Windows11上运行疑难解答,请执行以下操作:单击开始按钮或按Windows键并从菜单中选择设置。当设置打开时,选择系统>疑难解答>其他疑难解答。在右侧向下滚动,找到SearchandIndexing,然后单击Run按钮。选择Outlook搜索不返回结果并继续屏幕上的说明。当您运行它时,疑难解答程序将自动识别并修复问题。运行疑难解答后,打开Outlook并查看搜索是否正常。如

解决方法有:1、检查索引值是否正确:首先确认你的索引值是否超出了数组的长度范围。数组的索引从0开始,所以最大索引值应该是数组长度减1;2、检查循环边界条件:如果是在循环中使用索引进行数组访问,要确保循环的边界条件正确;3、初始化数组:在使用数组之前,要确保数组已经被正确地初始化;4、使用异常处理:在程序中可以使用异常处理机制来捕获索引超出数组界限的错误,并进行相应的处理。

如何通过索引提升PHP与MySQL的数据分组和数据聚合的效率?引言:PHP和MySQL是目前应用最广泛的编程语言和数据库管理系统,常常被用于构建web应用程序和处理大量数据。在处理大量数据时,数据分组和数据聚合是常见的操作,但如果不合理地设计和使用索引,这些操作可能会变得非常低效。本文将介绍如何通过索引来提升PHP与MySQL的数据分组和数据聚合的效率,并提

这篇文章将为大家详细讲解有关PHP返回一个字符串在另一个字符串中开始位置到结束位置的字符串,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。PHP中使用substr()函数从字符串中提取子字符串substr()函数可从字符串中提取指定范围内的字符。其语法如下:substr(string,start,length)其中:string:要从中提取子字符串的原始字符串。start:子字符串开始位置的索引(从0开始)。length(可选):子字符串的长度。如果未指定,则提
