第12/24周 并行执行计划

在这一期的性能调优培训里,我想详细讲解下SQL Server里的并行执行计划(Parallel Execution Plans) 。执行一个有并行执行计划的查询,意味着SQL Server从执行计划里进行必须的运算符需要使用多线程。首先我会介绍下并行执行计划里最常用的运算符,然后我们来分析下SQL Server是如何决定是否要使用并行执行计划。

并行运算符(Parallel Operators)

对于并行执行计划最常见的误解就是多线程只用于整个执行计划。这是错误的,因为SQL Server可以分配多个工作线程给所有可并行(parallelism-aware)运算符。这就意味者一个大型的并行计划可以消耗大量的线程。SQL Server在并行计划里区分2类运算符:可并行(parallelism-aware)运算符,和称为交换运算符(Exchange Operators)

  • 很多传统的运算符可以使用多线程来进行它们的工作,它们是可并行(parallelism-aware)运算符:索引扫描(Index Scan),索引查找(Index Seek),嵌套循环(Nested Loop),哈希连接(Hash Join),排序(Sort)等。
  • 交换运算符(Exchange Operators)是在并行执行计划里,用来分发和合并多线程之间的行。

SQL Server使用下列3个交换运算符:

  • Distribute Streams: 在并行计划中,从一个单线程里区域转变为多线程区域(接收记录的单个输入流,并生成多个输出流。)。
  • Repartition Streams: 在线程间重新分配行(例如,当前一个运算符是并行哈希连接)(处理多个流并生成多个记录流。)。
  • Gather Streams:在并行计划中,从多线程区域转变为单线程区域(处理几个输入流并通过组合这几个输入流生成单个记录输出流。)。

当你阅读并行执行计划时,你总会看到2种运算符的结合。每个执行计划必须生成一个单线程的结果,因此在并行执行计划的结尾,你总能看到Gather Streams运算符。

查询优化器是否生成一个并行执行计划也取决于你使用的查询结构是否会阻止并行计划,例如:

  • T-SQL 语句和SQL公共语言运行库的自定义函数(SQLCLR UDFs);
  • 内建函数,像OBJECT_ID(), ERROR_NUMBER(), @@TRANCOUNT等;

在并行计划里,也有很多查询结构会强制串行区域(这部分操作会使用并行计划):

  • 系统表扫描(System Table Scans)
  • 序列函数(Sequence Functions)
  • 向后扫描(Backward Scans)
  • 递归查询(Recursive Queries)
  • 表值函数(TVFs)
  • TOP

在你的并行计划里,串行区域越少,你的查询越快。当你下次写你的查询时,好好考虑这点。

什么时候使用并行(When to go parallel?)

每个执行计划都会被SQL Server分配一个成本因素(Cost Factor) 。成本因素就是用来告诉SQL Server这个执行计划有多贵的简单数字。这个数字越大,执行计划运行的关联成本就越高。

SQL Server有一个称为并行开销阀值(cost threshold for parallelism)的配置选项,用来定义成本因素,在哪个点查询优化会考虑使用并行计划。默认这个配置选项是5,也就说查询高于这个成本值,只要并行计划可行,就会使用并行计划。

当并行计划被查询优化器编译好后,最大并行度(Max Degree of parallelism(MAXDOP))选项定义对执行计划中的每个并行运算符可用线程数。我刚才提过,并行执行计划里的每个运算符都可以用多线程运行,而不是整个执行计划。当然在并行执行计划里,线程可以被前一个运算符共享和重用。可以通过服务器属性->高级->并行配置这些属性:

默认最大并行度(MAXDOP)选项值是0,因此SQL Server会默认将并行查询穿过所有分配给SQL Server的CPU内核。当你使用NUMA(Non Uniform Memory Access)系统时,这个会导致性能问题。最佳实践是限制MAXDOP选项值,在NUMA节点里的核心数(包括超线程的核心数)范围内。这样就可以保证SQL Server的并行计划呆在NUMA节点内

小结

这一期的性能调优培训里我讲解了SQL Server里的并行执行计划,你学到了在并行执行计划里涉及到的各种运算符,还有在SQL Server里你如何配置并行度。如果你想对并行计划有更深入的了解,可以看下…………(此次内容待完善)。

看完这篇文章,性能调优培训的第3个月就已经结束了,在下一个月我会讲解下SQL Server里的统计信息。请继续关注!

时间: 2024-08-12 07:02:02

第12/24周 并行执行计划的相关文章

12.24 ~ 12.30周训练计划+总结

12.24 min25筛裸题 https://loj.ac/problem/6053 补题 https://lydsy.com/JudgeOnline/problem.php?id=4036 fwt+子集反演 https://lydsy.com/JudgeOnline/problem.php?id=3302 树形dp https://lydsy.com/JudgeOnline/problem.php?id=4057 状压 https://lydsy.com/JudgeOnline/problem

第11/24周 重编译

今天我想谈下性能调优培训里的重编译(Recompilations ).当你执行一个查询,SQL Server里另一个变动使你执行计划的剩余部分无效,就会发生重编译.在那个情况下SQL Server需要保证你执行计划的准确性,重编译就会被触发.重编译会给你的SQL Server带来额外的CPU开销. 什么是重编译? 首先我想展示下编译和重编译之间的区别.2个星期前,我们讨论了SQL Server里的编译.当查询优化器把提交的查询转化为实际执行计划时,编译就会发生.这就是说编译在查询执行开始前就发生

2015.12.14-2015.12.20 大论文计划

利用一周时间完成大论文,大论文优先级大于前端学习 12.14周一,写第一章绪论部分; 12.15周二,写完第三章 12.16周三,写完第五章 12.17周四,写完中英文摘要,各章节总结重新增加内容 12.18周五,重修1,2章 12.19周六,重修3,4章 12.20周七,重修5章,写完第6章 附:前端研修的内容

Android开发之获取系统12/24小时制的时间

//通过DateFormat获取系统的时间 String currentTime=DateFormat.format("yyyy-MM-dd hh-mm-ss", new Date()).toString(); currentTime="通过DateFormat获取的时间:\n"+currentTime; //通过SimpleDateFormat获取24小时制时间 SimpleDateFormat sdf=new SimpleDateFormat("yyy

6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)

6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.) 余博伦· 2 个月前 原文链接:A Study Plan To Cure JavaScript Fatigue 作者:Sacha Greif 和大家一样,最近我也看了Jose Aguinaga写的How it feels to learn JavaScript in 2016. 显然这篇文章击中了人们的痛处.它在Hacker News上排了不止一次第一.同样也是/r/javascript上最火的一篇,在Med

2017.12.24(查找最接近元素等)

2017.12.24  贪心,分治综合习题(2) 1.查找最接近元素 思路:由题可知,n<=100000,m<=10000,如果每一个m都把这个非降序序列扫一遍的话,那么时间复杂的将要到达1010那么多,明显不合题意:所以,只能用二分查找来优化时间复杂度. 核心代码: int left=1,right=n,mid,bz=0; while(left<right-1){ bz=0; mid=(left+right)/2; if(k==num[mid]){ printf("%d\n&

12.21 php-fpm的pool;12.22 php-fpm慢执行日志;12.23 ;12.24

12.21 php-fpm的pool 1.添加pool: [[email protected] ~]# vim /usr/local/php-fpm/etc/php-fpm.conf 添加第二个pool: [hao1.com] listen = /tmp/hao1.sock listen.mode = 666 user = php-fpm group = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_

12.21 php-fpm的pool 12.22 php-fpm慢执行日志 12.23 open_basedir 12.24 php-fpm进程管理

12.21 php-fpm的pool php-fpm有一个概念叫pool,就是使用psaux看到的右侧的那一列,也就是它的池子, 如下图,我们在这里只定义了一个pool 其实他是支持定义多个池子的,每一个池子我们可以监听不同的sock,或者不同的tcpip,这样的话如果我们的nginx有好几个站点每个站点都可以使用不同pool,这样做的好处就是其中一个php502了,其他站点不收影响,(502很有可能是php资源不够了)如果你所有的网站都使用了同一个池子的话,其中一个网站发生了故障,比如程序员写

Error:(12, 24) 警告: [deprecation] android.hardware中的Camera已过时.android

问题:android studio编译项目时出现: Error:(12, 24) 警告: [deprecation] android.hardware中的Camera已过时 解决:(只是让其不提示) 1.app的 build.gradle中 1 android { 2 ... 3 lintOptions { 4 checkReleaseBuilds false 5 abortOnError false 6 7 } 8 } 2.根目录的build.gradle中 allprojects { ...