热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLServer性能分析及优化

image.png公司使用SQLServer作为数据库,工作中积累了很多SQL性能优化经验,为了自己查询和记忆方便,我的分类方式主要分为语法优化,子句优化和索引优化,可以根据自己所

《SQLServer性能分析及优化》 image.png

公司使用SQLServer作为数据库,工作中积累了很多SQL性能优化经验,为了自己查询和记忆方便,我的分类方式主要分为语法优化,子句优化和索引优化,可以根据自己所需直接查找到对应的优化建议。(比如使用!=好还是<>好,LIKE语句有什么优化建议&#8230;)

需要注意的是:

  1. 有些优化技巧是只能在SQLServer中使用,但更多的是标准SQL能够通用的优化技巧。
  2. 任何SQL优化都必须使用实际数据,脱离数据量谈优化都是耍流氓
  3. 本文所述的很多优化技巧,SQL的查询优化器也是会自己优化的,但是我们还是得学习下

先介绍SARG

SARG操作就是“一个范围内的匹配搜索操作”,就是SQL语句的WHERE条件,而且这个条件不能触发全表扫描。

可以理解为:没有触发全表扫描的搜索条件

举几个例子:

  • Like语句是否属于SARG取决于所使用的通配符的类型,原因是通配符%在字符串的开头使得索引无法使用

如:name like ‘张%’ ,这就属于SARG
而:name like ‘%张’,就不属于SARG。

  • 使用or会引起全表扫描

如:Name=’张三’ and 价格>5000 符号SARG,
而:Name=’张三’ or 价格>5000 则不符合SARG。

其他介绍请看后缀子句的介绍。

子句优化

SQL优化建议很多且难以分类,所以我以子句为粒度来对SQL优化建议进行分类,尽可能让我们看到子句就知道需要其对应的优化建议。这里为了理解方便,将SQL所有子句根据where子句的位置分割为前缀子句和后缀子句,where子句属于后缀子句。

前缀子句

SELECT
  • 避免使用SELECT * 的语法:应该完整的写上所需要的字段,并且要按照表中字段的物理顺序书写,不但可以防止表结构改变导致的代码错误,也可以防止大数据量的提取导致SQL效率低下。
INSERT
  • 避免使用INSERT INTO table VALUE(?,?,?):需要在table后完整地写上需要插入的字段,按照字段的物理顺序书写,而不是用?代替,这样可以提高效率。
UPDATE
  • 暂无
DISTINCT
  • 尽量少用DISTINCT或用其他方法去重:DISTINCT解决重复数据很方便,但是他会临时产生一张工作表,通过排序来删除重复的数据,因此会增加SQL的I/O次数和时间损耗。
COUNT
  • COUNT统计NULL有差异:COUNT(*)和COUNT(1)会统计NULL值,COUNT(列名)不会统计NULL值
  • 尽可能使用COUNT(1):官方文档显示1等价于*,因为大家都传言1快过*,所以官方对1做了优化,虽说等价,但还是推荐使用COUNT(1),保证统一。
  • 单列索引可以提升COUNT性能:COUNT(*)和COUNT(1)都会自动遍历寻找最小的索引,考虑在一个最短的列建立一个单列索引,会极大的提升性能。

后缀子句

OR
  • 尽可能少用: 会引起全表扫描(不符合SARG),可以考虑用UNION替换。
LIKE
  • [通配符](*,?,_,%)不要在字符串的开头:会导致索引失效而全表扫描(不符合SARG)
IN / NOT IN
  • 尽可能少用: 会引起全表扫描(不符合SARG),类似OR,可以考虑用EXISTS替换。
EXIST
  • 可以使用EXIST和NOT EXIST 可以代替 IN和NOT IN:这样可以避免SARG,但是应该需要考虑EXITS中的语句执行速度,如果EXITS中的语句执行很慢,数据有多少条就需要执行多少次,这样反而会拖累速度,不一定EXIST比IN好,应该考虑实际数据情况。
WHERE
  • 将能够筛选出最多数据的条件放在最右:因为默认SQL SERVER采用自右向左的顺序解析where子句,所以应该将可以过滤掉大量记录的条件必须写在where子句的末尾。
ORDER BY
  • 建议参数为索引列,且索引列不能有NULL值:参数中有任何一种索引都有助于SELECT的性能提高。注意如果索引列里面有NULL值,优化器将无法优化,所以需要先排除NULL。(SQL中很多地方存在NULL都会影响SQL执行性能,建议在不破坏业务需求的情况下习惯性排序掉NULL值)。
GROPU BY
  • 建议参数为索引列,且索引列不能有NULL值:参数中有任何一种索引都有助于SELECT的性能提高。注意如果索引列里面有NULL值,优化器将无法优化,所以需要先排除NULL。(SQL中很多地方存在NULL都会影响SQL执行性能,建议在不破坏业务需求的情况下习惯性排序掉NULL值)。

  • 要在group by之前先过滤数据:提高group by语句的效率,可以将不需要的记录在group by之前过滤掉

语法优化

  • 避免使用子查询,使用连接查询:子查询属于笛卡尔集,嵌套过多会导致数据量指数级增长,如果不能避免希望能够先过滤尽可能多的数据。
  • 数据表起别名:可以利于优化器优化。
  • 不要使用负逻辑: 不满足SARG,会直接触发全表扫描。当表较大时,会严重影响系统性能,可以用别的操作来代替。
  • 将逻辑运算从等号左边移到右边:比如把a*2>4 改为 a>4/2。

索引优化

  • 索引不被使用的几种情况:null判断,比较,not函数
  • 索引列上不要计算
  • 索引列上>= 代替 >
  • 避免频繁的索引重建
  • 索引数量不超过列总数的40%

感谢

  • 数据库性能的优化
  • 高并发update的 死锁产生原因
  • 快速理解聚集索引和非聚集索引
  • SQL索引一步到位

推荐阅读
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
author-avatar
平凡数码广场
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有