SQLServer性能分析及优化

image.png

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

需要注意的是:

  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%

感谢

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容