设为首页 收藏本站
查看: 1090|回复: 0

[经验分享] SQL Server 并行操作优化,避免并行操作被抑制而影响SQL的执行效率

[复制链接]

尚未签到

发表于 2018-10-18 12:47:07 | 显示全部楼层 |阅读模式
  为什么我也要说SQL Server的并行:
  这几天园子里写关于SQL Server并行的文章很多,不管怎么样,都让人对并行操作有了更深刻的认识。
  我想说的是:尽管并行操作可能(并不是一定)存在这样或者那样的问题,但是我们不能否认并行,仍然要利用好并行。
  但是,实际开发中,某些SQL语句的写法会导致用不到并行,从而影响到SQL的执行效率
  所以,本文要表达的是:我们要利用好并行,不要让一些SQL的写法问题“抑制”了并行,让我们享受不了并行带来的快感
  关于SQL Server的并行:
  所谓的并行,指SQL Server对于那些执行代价相对较大(这个相对跟你的设置有关)的SQL时,如果数据库服务器存在多颗CPU,
  SQL Server查询引擎会采用并行的方式,也即采用多颗CPU参与整个运算过程,每颗CPU“分担”一部分计算任务,最后汇总合并各个CPU的计算的一种行为
  有时候,不当的并行查询不但不会加快查询的速度,想反会拖慢查询的效率,如果采用不当的并行操作,甚至会影响到整个服务器的稳定性。
  所以SQL Server 究竟在多大代价下启用并行,是由配置的,这个配置可根据具体的情况做修改,有人说这个值的单位是“秒”,貌似没见过权威的资料说过到底单位是什么,这里暂不追究
  有清楚这个阈值单位的园友情不惜赐教,谢了

  尽管并行操作可能存在这样活着那样的问题,但是我们不能因噎废食,利用好并行,往往总是利大于弊。
  但是并不是所有的执行代价较大SQL都能用到并行操作,实际开发中,有一些SQL的写法会抑制到并行操作,结果,导致整个SQL语句(存储过程)的效率上不去。
  下面来举例说明。
  并行查询是如何变成了串行的:
  如下是一个非常简单的查询操作,这些写法下,默认情况下开启了并行,可以看到,一共开启了8个线程来对SQL语句做计算。

  当然这SQL的执行效率还算不错,CPU时间是622毫秒,执行总时间是130毫秒,
  这里不要弄混淆了,CPU时间的633毫秒,是8个CPU一共消耗的CPU时间,大于总的执行130毫秒很正常的

  下面创建一个非常简单的函数,
CREATE function [dbo].[fn_justFunction](@p_date date)returns dateasbegin  
    return @p_dateend
  这个函数并没有什么实际意义,执行也非常简单,传入一个时间,返回这个时间,

  当然这里只是为了下面的操作演示,你完全可以说我蛋疼,我只是为了演示并行被抑制的现象
  翻翻你的SQL代码,有没有类似这种写法?
  然后我们这么写这个查询,就是在查询条件上这么处理CreateDate>dbo.fn_justFunction('2015-1-1')(注意不是表的列,而是函数作用在查询条件上),
  注意这个函数并不影响任何查询结果,传入的2015-1-1,返回位依旧是2015-1-1,但是这么一变化,并行就变成串行的了,
  SQL执行期间只有一个CPU飚了起来,使用了到达80%左右,,与此同时其他CPU跟没事人一样,也不上来帮忙,还是很闲
  还记得上面并行操作方式执行时间是多少么?130毫秒,现在粗看起来是多少,这里是4S,也就是4000毫秒

  可以看到,并行操作和串行操作的效率差别还是很大的,对于CPU的利用也不充分(当然我不是强调一定要用满所有的CPU才算合理)
  再次强调一点,这里并不是在表的字段上加函数抑制了索引什么的,纯粹的影响到的是并行操作。
  当然,抑制并行的写法不单单是在查询条件在使用函数,实际开发中,影响会更大,
  因为实际业务中数据有可能会更大,SQL也可能更加复杂,这种情况可能更加难以甄别。
  比如连接条件上,如下,连接条件上使用函数导致无法使用并行的情况,也是实际开发中遇到的
  select * from TableA a inner join TableB b on a.id=b.id and a.Column=dbo.function(@Variable) where ***
  当然抑制到并行操作的不单单只有这两种写法,还有可能潜在其他类似的写法也会影响到并行查询。
  这就要求我们在写SQL的时候,不但要注意不能再字段上使用函数(无法使用该字段上的索引),同样,查询条件上也尽可能不要使用函数,有可能影响到并行操作。
  总结起来有一下几种情况会抑制到并行的使用(以后发现再更新):
  1,将函数之类的操作作用在查询条件上
  比如:CreateDate>dbo.fn_justFunction('2015-1-1')
  2,将函数之类的操作作用在连接条件上
  比如:select * from TableA a inner join TableB b on a.id=b.id and a.Column=dbo.function(@Variable)  where ***
  3,强函数之类的操作作用在查询列上
  比如:FunctionName(ColumnName)>55,这种情况,如果查询列上有索引,不仅仅是抑制索引,还会抑制并行
  如何处理并行操作被抑制的情况:
  如果要解决类似这些个问题,该怎么办?
  其实也很简单,建议查询条件通过函数运算之后赋值给一个变量,用变量去作为查询条件进行查询。
  再次开始了愉快的并行,享受并行带来的快感。

  对于连接条件上的函数处理也类似,将结果计算出来之后,保存在一个变量中,把变量写在连接条件中,
  当然可能有其他办法,我暂时还没有想到。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-623211-1-1.html 上篇帖子: CentOS6.7 安装配置LDAP Server-zenge 下篇帖子: SQL Server 环形缓冲区(Ring Buffer) -- RING_BUFFER_SECURITY_ERROR 诊断安全相
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表