SQL SERVER 的SQL语句优化方式小结

所属分类: 数据库 / MsSql 阅读数: 739
收藏 0 赞 0 分享
1、SQL SERVER 2005的性能工具中有SQL Server Profiler和数据库引擎优化顾问,极好的东东,必须熟练使用。

2、查询SQL语句时打开“显示估计的执行计划”,分析每个步骤的情况

3、初级做法,在CPU占用率高的时候,打开SQL Server Profiler运行,将跑下来的数据存到文件中,然后打开数据库引擎优化顾问调用那个文件进行分析,由SQL SERVER提供索引优化建议。采纳它的INDEX索引优化部分。

4、但上面的做法经常不会跑出你所需要的,在最近的优化过程中CPU占用率极高,但根本提不出我需要的优化建议,特别是有些语句是在存储过程中并且多表联立。这时就需要用中级做法来定位占用CPU高的语句。

5、还是运行SQL Server Profiler,将运行结果保存到某个库的新表中(随便起个名字系统会自己建)。让它运行一段时间,然后可以用
select top 100 * from test where textdata is not null order by duration desc
这个可以选出运行时间长的语句,在ORDER BY 中可以替换成CPU、READS,来选出CPU占用时间长和读数据过多的语句。
定位出问题的语句之后就可以具体分析了。有些语句在执行计划中很明显可以看出问题所在。
常见的有没有建索引或索引建立不合理,会出现table scan或index scan,凡是看到SCAN,就意味着会做全表或全索引扫描,这是带来的必然是读次数过多。我们期望看到的是seek或键查找。

6、怎么看SQL语句执行的计划很有讲究,初学者会过于关注里面显示的开销比例,而实际上这个有时会误导。我在实际优化过程中就被发现,一个index scan的执行项开销只占25%,另一个键查找的开销占50%,而键查找部分根本没有可优化的,SEEK谓词就是ID=XXX这个建立在主键上的查找。而仔细分析可以看到,后者CPU开销0.00015,I/O开销0.0013。而前者呢,CPU开销1.4xxxx,I/O开销也远大于后者。因此,优化重点应该放在前者。

7、如何优化单个部分,一个复杂的SQL语句,SQL SERVER会很聪明地重组WHERE后的语句,试图匹配索引。选中带优化的步骤,选择旁边的‘属性”,再选择其中的“谓词”,将其中部分复制下来,这部分就是分解后的WHERE 语句,然后在查询界面中select * from 表 where 刚才复制下来的“谓词”。这个就是需要优化的部分,既然已经走到这一步了,大部分人应该能手动建立索引了,因为这里的WHERE语句比之前的肯定简单不少。(在我项目中原始SELECT语句的WHERE部分有10个条件组合,涉及6个字段,提取出来要优化的部分就4个条件,涉及到3个字段。新的索引建立后,CPU占用率一下子就降低了,而且新建立的索引涉及的字段属于不常UPDATE的部分,频繁的读写操作不会影响UPDATE的效率)

8、以上就是优化的思路,最后提一些优化过程或是系统设计时中需要注意的问题。
A、尽量避免用select * from xxx where abc like '%xxx'类型的模糊查询,因为%在前面的话是无法利用到索引,必然会引起全量SCAN操作。应该找寻替代方式或用前置条件语句把like查找之前的行数减到最低。
B、尽量避免对大表数据进行select top n * from xxx where xxxx order by newid()的取随机记录的操作。newid()操作会读全量数据后再排序。也会占用大量CPU和读操作。可以考虑用RAND()函数来实现,这方面我还在研究中,对于整表操作比较好弄,比如id>=(select max(id) from table)*rand()。但如果取局部数据的随机记录还需要思量。
C、在SQL Server Profiler记录中会看到Audit Logout会占用大量CPU和读写等操作。查了一些资料称是某个链接在某次连接过程中执行SQL语句产生的总数,不用过于担心。看下来的确似乎这样,很多Audit Logout的CPU和IO消耗量和之前优化的语句基本一致。所以在第5点我提的SQL语句用textdata is not null条件把Audit Logout给隐去。
D、两个不同字段OR语句会导致全表扫描。例如 where m=1 or n=1。如果建立一个索引是m和n,同样会引起scan,解决方法是给m和n分别建立索引。测试12万条数据的表,索引建立错误的情况下IO开销高达 10.xxx,分别建立索引后,全部变成0.003,这个反差是非常巨大的。虽然会引起INSERT操作的性能问题,但毕竟大部分瓶颈在SELECT的读操作上。
E、索引查找(Index Seek)和索引扫描(Index Scan),我们需要的是前者,而引起后者的原因通常是某个索引里的字段多余要查找的,例如索引建立在A和B两个字段,而我们只要查找A,则会导致 INDEX SCAN。建议针对单独的A建立索引,以形成索引查找。
F、对于小表不建议建立索引,特别是几百的数据量,只有上千上万级别的数据建立索引才有效果。

数据库优化是很深的学问,在数据库设计时就应该注意,特别是最后提到的A、B两点,尽可能在设计初期避免。
更多精彩内容其他人还在看

SQL Server评估期已过问题的解决方法

这篇文章主要为大家详细介绍了SQL Server评估期已过问题的解决方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

sqlserver还原数据库的时候出现提示无法打开备份设备的解决方法(设备出现错误或设备脱)

今天在恢复数据库的时候,因为是异地部分还原,出现提示 无法打开备份设备 E:\自动备份\ufidau8xTmp\UFDATA.BAK 。设备出现错误或设备脱,这里分享一下解决方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

SQL数据库存储过程示例解析

这篇文章主要针对SQL数据库存储过程示例进行解析,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SQL Server 2012 安全概述

这篇文章给你概括介绍了SQL Server 2012里的基本安全概念。你学到了一些常见的数据威胁,探寻了SQL Server背后的设计理念,学习了在整个系列文章看到的一些安全术语,算是一篇比较非公式化的开篇,希望能够勾引起大家对于sql安全的兴趣
收藏 0 赞 0 分享

探讨select in 在postgresql的效率问题

这篇文章主要介绍了探讨select in 在postgresql的效率问题 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server 2012 身份验证(Authentication)

这篇SQL Server安全文章,我们学习了SQL Server里的多个验证选项。Windows集成身份验证是最安全的,但并不是都是可行的,微软多年来已经让SQL Server验证更加安全。
收藏 0 赞 0 分享

SQL性能优化之定位网络性能问题的方法(DEMO)

这篇文章主要介绍了SQL性能优化之定位网络性能问题的方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server 2016里的sys.dm_exec_input_buffer的问题

这篇文章主要介绍了SQL Server 2016里的sys.dm_exec_input_buffer的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server删除表及删除表中数据的方法

本文介绍SQL Server中如何删除表,如何删除表中的数据。在删除表数据时有delete和truncate两种方法,delete和truncate有什么区别呢
收藏 0 赞 0 分享

sqlserver 因为选定的用户拥有对象,所以无法除去该用户的解决方法

这篇文章主要介绍了sqlserver 因为选定的用户拥有对象,所以无法除去该用户,因为是附加数据库选择了与源服务器一样的用户导致
收藏 0 赞 0 分享
查看更多