首页 存档 技术 查看内容

SQL SERVER全面优化:写出好语句是习惯

2018-3-30 13:00 |来自: 互联网 376 0

摘要: 点击上方“蓝字”可以关注我们哦 |转载自:cnblog |原文链接:http://www.cnblogs.com/double-K/p/5568360.html 前几篇文章已经从整体提供了诊断数据库的各个方面问题的基本思路…也许对你很有用,也许你觉得离自己 ...

点击上方“蓝字”可以关注我们哦



|转载自:cnblog

|原文链接:http://www.cnblogs.com/double-K/p/5568360.html



前几篇文章已经从整体提供了诊断数据库的各个方面问题的基本思路…也许对你很有用,也许你觉得离自己太远。那么今天我们从语句的一些优化写法及一些简单优化方法做一个介绍。这对于很多开发人员来说还是很有用的!为了方便阅读给出前文链接:SQL SERVER全面优化-Expert for SQL Server 诊断系列


首先还是贴出我的座驾


好的语句就像这辆车,跑的又快又帅气!今天这里介绍一些技巧让你可以改装一下自己的车!网上确实有好多好多好多好多SQL 语句优化的文章,什么 优化大全 ,100个优化注意 ,确实整理了好多好多。那么为什么我也要凑热闹写一篇呢? 好吧我也不知道!


重中之重语句执行顺序


在QQ群和人聊天的时候突然有位群友说:我才知道原来语句走索引是按照select 的字段筛选的! 振振有词,非常肯定!另一个群友反问update呢 ? 看起来很小白的问题,但确实让我很震惊!所以我们先看看语句的执行顺序


如果我没记错这是《SQL SERVER 2005技术内幕查询》这本书的开篇第一章第一节。书的作者也要让读者首先了解语句是怎么样的一个执行顺序,因为不知道顺序何谈写个好语句?


查询的逻辑执行顺序:


(1) FROM

(3) JOIN (2) ON

(4) WHERE

(5) GROUP BY

(6) WITH {cube | rollup}

(7) HAVING

(8) SELECT (9) DISTINCT

(10) ORDER BY


标准的SQL 的解析顺序为:


(1).FROM 子句 组装来自不同数据源的数据

(2).WHERE 子句 基于指定的条件对记录进行筛选

(3).GROUP BY 子句 将数据划分为多个分组

(4).使用聚合函数进行计算

(5).使用HAVING子句筛选分组

(6).计算所有的表达式

(7).使用ORDER BY对结果集进行排序


执行顺序:


1.FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1


2.ON:对vt1表应用ON筛选器只有满足 为真的行才被插入vt2


3.OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2 生成t3如果from包含两个以上表则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束


4.WHERE:对vt3应用 WHERE 筛选器只有使 为true的行才被插入vt4


5.GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5


6.CUBE|ROLLUP:把超组(supergroups)插入vt6 生成vt6


7.HAVING:对vt6应用HAVING筛选器只有使 为true的组才插入vt7


8.SELECT:处理select列表产生vt8


9.DISTINCT:将重复的行从vt8中去除产生vt9


10.ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10


11.TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者


我们了解了sqlserver执行顺序,请以前不知道的看官们,反复试验反复记忆!那么我们就接下来进一步养成日常sql好习惯,也就是在实现功能的同时又考虑性能的思想!


设计思路


具体写法的优化请不要着急,那都是小儿科!


设计思路说的有点大了,下面介绍几个最常见的设计问题!


循环改批量


循环单条操作,请改成批量操作,如果没办法修改,请尽量想办法修改!这算是最常见的吧:


1应用代码端一记 for 循环再恶心点的每次打开关闭连接,跑个几分钟,数量大点几小时。请把你的每次for循环出来的结果放在一个datatable,list啥的,不要找到一条就往数据库写一条!


2数据库中的游标也是差不多的道理,如果有可能不用游标循环一条一条处理,请尽量不要使用。如果自己认为必须用,也请问问别人是否可以有其他方式做批量!


3如果没法避免一条一条的写入,那么在处理前显示开启一个事务 begin tran 在处理完成后 commit 这样也要比不开显示事务会快很多!


上个小例子:

create table test_0607 (a int,b nvarchar(100))

declare i int

set i = 1

while i

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部