查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划。很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用手段。另外如果你是一个公司的dba 并且你对你所维护的数据库了如指掌,对业务也有相当深刻的了解那么查询提示也是你的一把利器。
但是,你所应用的提示是在现在的场景中基于现有的环境下,相对是一个好的方式,不能确保你所给予的提示永久有效,并且随着时间推移,数据量的变更,你所加的提示可能成为噩梦。所以没有充分的把握不要轻易使用提示。
下面说一说option (querytraceon 8649) 开启强制并行,个人认为这个提示真心是个好东西(2005不支持),sql优化器经常会让一个开销较大的语句使用串行(稍后发文),这个时候当你加上option (querytraceon 8649) 会吓你一跳 30秒变2秒?
下面作个例子说明一下:
串行计划
并行计划
时间缩短了将近一半(本机配置可怜...在一台好的服务器效果会更明显)
我这可怜的配置
资源使用情况就不贴图了,具体的并行执行原理请参见大神 指尖流淌的博客
http://www.cnblogs.com/zhijianliutang/p/4149850.html
我们继续...这相当于消耗更多的资源来换取时间,但相对与要求反应更快的今天来说无疑是必要的选择。
那么为什么SQL优化器生成一个串行计划,而不是“明显更好的”并行计划,总有一个原因。配置设置被设置为一个最大程度的并行(前面的maxdop 1),或者只有一个逻辑处理器可用的SQL服务器,或并行抑制操作,基数估计错误,成本核算模型的局限性。
抛开其他因素我们来说一下因为语句写法而造成的优化器不能选择并行计划,大致一下几点:
- 修改表变量操作(查询是可以的)
- 使用标量函数 (这个是最常见查询不能开启并行的原因)
- CLR执行数据访问的标量函数。
- 随机的内在功能,如:object_name,encyptbycert等。
- 使用系统表,如:sys.tables。
还有一些功能是不能并行完成的,举几个常用情况如:
- top
- row_number
- 多语句表值函数。
- 递归CTE
提到并行就一定要提一下maxdop了,调整好这个参数也是很必要的,不一定是越大越好哟~ 等待类型CXPACKET很大程度上是因为过度并行导致的等待。
另外有个疑问希望大神们帮我解答union all的时候真的没法并行执行么 ,当然指的是union的每个部分一起执行,然后合并结果。
曾经看到这个就傻傻的以为可以并行了...其实只是union的每个语句并行而已...