Degree of Parallelism(并行度)

    一个查询使用并行来处理时,SQL Server为该查询分配多个线程,每个线程使用一个CPU进行操作。Degree of Parallelism就是SQL Server为并行查询分配的线程数量,也表明这个并行查询将使用多少个CPU进行并行处理。
    Exchange Oprators(交换操作)
    查询语句的执行计划中,通常是并行操作和串行操作结合在一起。并行操作要求将输入数据流(data stream)切分成多个(即degree of parallelism)部分,分别分配给各个线程进行并行处理。并行查询包括几个数据流的交换操作(exchange operator),用以管理并行计划的执行。
    Distribute Steams
    执行计划中显示为Parallelism/Distribute Steams。通常情况下,如果在一个串行操作之后紧接着一个并行操作,则这个并行操作将从前一个串行操作接收一个input stream。Distribute Steams就是并行查询中将单个input stream分发到多个output stream中的操作。
    例如一个serial table scan产生一个4000记录的output stream,假设在这个table scan之后是一个并行操作,则在这两个操作之间必须需要一个Distribute Steams操作,向并行操作的各个线程分发input stream。如果degree of parallelism为4,SQL Server根据关键字段,将这个4000记录的stream分发成4个大致相当的stream,分别作为4个线程的input。< /font>
    Distribute Streams操作之后,每一条input stream中的记录,将出现在某一个output stream中,记录的内容和格式不会发生任何变化。SQL Server自动在output stream中保留input stream中各记录的相对顺序。
    通常,将使用Hashing以确定每一条输入记录被分发到哪一个output stream中。
    Gather Streams
    执行计划中显示为Parallelism/Gather Streams。在并行操作结束之后,输出结果保留在多个stream中。Gather Streams将并行操作的多个output stream收集到单个stream中。
    Gather Streams对多个stream进行合并过程中,记录的内容和格式不会发生任何变化。如果各个input stream都是排序的,则Gather Streams的output stream也是排序的。
    Redistribute Streams/Repartition Streams
    执行计划中显示为Parallelism/Repartition Streams。在一系列的并行操作中,在某个并行操作之后,可能需要对各个stream进行重新组合,才能够进入下一个并行操作。< /font>
    例如Merge Join、Hash Join,都需要两个input。这些操作的并行计划中,每个并行的线程都应当拥有两个独立的input,各自执行Merge Join、Hash Join操作,在并行Merge/Hash Join之后,使用Gather Streams操作,就得到完整的Merge/Hash Join的结果。如果在Merge/Hash Join前是一系列的并行计划,则在进入Merge/Hash Join时,各个并行线程拥有的stream可能不满足"独立的input"这个条件,此时就需要对进入Merge/Hash Join的各个stream进行重组,以使并行的各个线程独立的完成Merge/Hash Join中的一部分。
    每一条input stream中的记录,在Repartition Streams操作之后将出现在其中一个output stream中,记录的内容和格式不会发生任何变化。如果各个input stream都是排序的,则Repartition Streams的各个output stream也是排序的。
 
    示例< /div>

    示例中要使用到2个table:
    TblBuyerItem(
        UserID NVARCHAR(40) NOT NULL,
        OrgID NVARCHAR(40) NOT NULL,
        ItemID NVARCHAR(40) NOT NULL)
    这个表的Clustered Index:OrgID,ItemID,记录数为150万。
    #alert_asn_shipoverdue(
        ORG NVARCHAR(40) NOT NULL,
        ITEM NVARCHAR(40) NOT NULL,
        VENDOR NVARCHAR(40) NOT NULL)
    这是个临时表,没有PK,没有任何index,记录数150。
执行的SQL如下(没有使用到TblBuyerItem的Clustered Index):
    SELECT a.UserID
    FROM TblBuyerItem a
    INNER JOIN #alert_asn_shipoverdue b ON b.ORG=a.OrgID AND b.ITEM=a.ItemID
    OPTION(MERGE JOIN)
    执行计划如下图(裁减掉了个别步骤,点击可以放大查看):

    执行计划中,图标右下脚有个黄色小圆圈,里面有三个并行小箭头,则表明这个操作是并行执行的。
    并行处理中的stream数据流如下图所示:
   
 
    上图示例degree of parallelism为3时的执行情况。执行过程介绍如下:
    先在#alert_asn_shipoverdue上执行table scan,然后根据key column ORG、ITEM的值,为并行的Merge Join操作将#alert_asn_shipoverdue的数据分发到三个stream中,假设编号分别为B1、B2、B3。三个线程各自对所获得的stream创建bitmap,然后进行排序。
    接下来,三个线程并行的在TblBuyerItem上执行Clustered Index Scan。操作完成后每个线程获得一个output stream,假设编号分别为A1'、A2'、A3'。现在A1'、A2'、A3'还不能与B1 、B2、B3匹配成A1'-B1、A2'-B2、A3'-B3,独立的进行Merge Join操作,因此根据key column OrgID、ItemID的 值,对A1'、A2'、A3'执行Repartition Streams操作,为接下来的Merge Join重组A1'、A2'、A3',并且使用bitmap过滤记录。假设重组后的stream分别编号为A1、A2、A3,此时,三个线程分别使用A1 -B1、A2-B2、A3-B3作为输入,执行Merge Join操作。在Merge Join操作前,两个input都必须是经过排序的,因此每一个stream在进入Merge Join操作前都有一个Sort操作。
    最后,Gather Streams操作从三个线程的output stream中收集合并记录集,得到完整的Merge Join结果记录集。
 
    Parallel query并不能节约内存、CPU的资源开销,因为将stream进行Distribute、Repartition、Gather都需要消耗更多的资源。但是Parallel query也许可以节约query的执行时间。
   
    Bitmap(位图)
    在上面的示例中,可以看到Bitmap/Bitmap Create的操作。
    在MANY-TO-MANY的Join中,两个表可能存在大量不匹配的记录。在上面的示例中,#alert_asn_shipoverdue的记录只有150,而TblBuyerItem的记录是1,500,000,如果直接对两个表进行 Merge Join,就必须为TblBuyerItem的1,500,000记录进行排序,这是一个成本非常高的操作。而在1,500,000记录中,只有少量记录符合匹配条件。Bitmap操作在Join操作前,快速的对数据进行一次初步的过滤,减少Join操作的开销。
    Bitmap in Merge Join
    仍以上面的示例来说明,在Parallelism/Distribute Streams操作之后,每个线程得到一个input stream,接下来各个线程为自己的stream创建bitmap。我们假设分配给线程1的stream编号为B1。Bitmap创建完成后,包含一系 列0、1的值,为1的位代表对应于这一位,该stream中存在相应的记录;为0的位代表对应于这一位,该stream中不存在相应的记录。在 Parallelism/Repartition Streams操作时,从input stream中循环取出每条记录,先确定该记录应当进入哪一个output stream中。我们假设某一条记录被确定应当放入编号为A1的output stream,这个output stream A1将与stream B1匹配,被分配给线程1,作为线程1 Merge Join的两个输入。接下来SQL Server使用这条记录,查询与output stream A1对应的stream B1的bitmap。如果相应的位值为0,则说明这条记录在B1中不可能存在匹配的记录,因此这条记录被忽略掉,不会放入output stream A1中;如果相应的位值为1,则说明这条记录在B1中可能存在匹配的记录,该记录被放入output stream A1,继续在后续的Merge Join中进行精确的匹配。
    关于bitmap具体如何创建还不清楚,猜想大致应当是如下的一个过程:使用hash算法进行操作,在查询优化期间基于#alert_asn_shipoverdue 的Join字段ORG、ITEM可能出现的唯一值数量而确定bitmap的大小。这个过程和Hash Join中确定hash table buckes数量(和大小)有点类似。执行期间,先使用这个bitmap大小的值创建bitmap,初始化各个位均为0。然后为#alert_asn_shipoverdue循环,对每一个ORG、ITEM的组合值进行hash,得到的hash value对应于bitmap中的某一个位,将这个位设为1。
    基于上面bitmap的创建过程,在Parallelism/Repartition Streams操作时,某一条记录被确定进入哪一个output stream之后,即可以找到相对应stream的bitmap。对这条记录OrgID、ItemID的值,使用在bitmap创建时相同的hash算法,用得到的hash value查找对应的位。
 
    下面看一下示例中bitmap的使用带来的效果(点击可以放大查看):
 
    在对TblBuyerItem进 行scan时,Row Count为1,543,050。在Repartition Streams操作中,WHERE:(PROBE([Bitmap1002])=TRUE)表明对bitmap的使用,Row Count 3,138。另外,从上图中可以看出,示例的SQL实际执行时使用了8 CPU。
    附加说明:在上面的示例中,#alert_asn_shipoverdue很小,并且bitmap的create 和probe过程,其实已经和Hash Join差不多。事实上,让SQL Server自动选择Join Type时,使用的是Hash Join(参考[Join Type实例说明],使用的是同样的示例)。使用Hash Join时用的是serial方式,耗时4秒多;上面的示例耗时2秒;上面示例不使用并行处理(MAXDOP 1)时,耗时1分30多秒。
 
    Merge Join中,在outer input的分支进入Merge Join前,必须有一个Sort操作,SQL Server才能使用bitmap。这是因为这个Sort操作使得整个outer input的分支处理完毕之后,才开始inner input分支的执行,最后再进入Merge Join操作。这样inner input分支执行时,才能使用在outer input分支上创建的bitmap。如果没有这个Sort操作,SQL Server会同时开始处理outer input分支和inner input分支,这样是无法使用bitmap的。
    我们可以在上面的示例上做一个验证。假如在#alert_asn_shipoverdue有一个clustered index(ORG,ITEM),那示例中的SQL语句执行时会是什么状况?在(ORG,ITEM)上创建clustered index后,执行计划变成下图所示(点击可以放大查看):
    对#alert_asn_shipoverdue的Table Scan变成了Clustered Index Scan,得到的stream是按照ORG、ITEM排序的。
      
    现在,在Parallelism/Distribute Streams操作前的stream是按ORG、ITEM排序的,因此Distribute Streams的各个output stream也是按照ORG、ITEM排序的,因此这个outer input分支在Merge Join前不再需要Sort操作,这样的话就无法使用bitmap了。
    从执行计划图中可以看到,inner input的分支,在TblBuyerItem的Table Scan之后,箭头的大小一直到Merge Join操作没有变化,说明在这个分支上一系列的操作中,记录数基本上没有什么变化。下图是TblBuyerItem的Table Scan和Parallelism/Repartition Streams的详细信息(点击可以放大查看):
 
    在这个验证中,没有使用bitmap的平均执行时间是1分10秒。
 
    Bitmap in Hash Join
    Hash Join中的bitmap,总体上来讲跟Merge Join中的处理是一样的。在build input(outer input)上构造hash table时是并行处理的,构造hash table的同时也为每个build input的stream创建bitmap。当整个build阶段完成后,再开始probe阶段,因此在probe阶段执行时已经可以使用bitmap, 接下来的操作就跟Merge Join中Probe Bitmap操作完全一样。
 
    SQL Server只在Parallel Query中使用bitmap,估计是Probe Bitmap结合Parallel Query中的Repartition操作,可节约的成本比较明显。在Serial Query中,额外的去Probe Bitmap,可能对查询的执行并不能带来明显的改善。
 
    OK,It's over now. 下面回顾一下示例的语句在各种情况下的执行效果:
       
 
    参考:
    MSDN - Parallel Query Processing
    MSDN - Bitmaps in Microsoft SQL Server 2000
    MSDN - Logical and Physical Operators

转载于:https://www.cnblogs.com/wayne-ivan/archive/2007/06/27/797062.html

Parallel Query Bitmap相关推荐

  1. oracle ora_p0,ORA-12801: error signaled in parallel query server P005

    昨天有个分区表,交换了30多个分区(将业务表30多个分区交换到历史表,然后删除业务表这30多个分区),然后今天早上收集统计信息的时候报错了,请教各位,这个需要重建索引吗?为什么收集统计信息的时候会报错 ...

  2. ORA-12801: error signaled in parallel query server PZ99分析

    分析结论 这个案例本身很简单,不难,就是想和大家分享下(主要是ORACLE的初学者,牛人请无视之) 1,查询SQL的WHERE条件列的数据类型一定要明确 2,查询报错的几个ORACLE错误,要学会分析 ...

  3. ORA-12805: parallel query server died unexpectedly ORA-04030 (sort subheap,sort key) 原因排查与解决方法

    ORA-12805: parallel query server died unexpectedly ORA-04030 (sort subheap,sort key) 原因排查与解决方法 参考文章: ...

  4. Oracle Parallel Query

    Oracle Parallel Query(OPQ)可以将一个SQL statement分成多个片(chunks),然后在独自的CPU上通过多个process(子查询)进行并行运行.每个子查询同时读取 ...

  5. Oracle Parallel Query(OPQ)

    日月明王BLOG   http://sunmoonking.spaces.live.com      Oracle Parallel Query(OPQ)可以将一个SQL statement分成多个片 ...

  6. Oracle 19c VLDB and Partitioning Guide 第8章:Using Parallel Execution 读书笔记

    本文为Oracle 19c VLDB and Partitioning Guide第8章Using Parallel Execution的读书笔记. 并行执行是通过使用多个进程将多个 CPU 和 I/ ...

  7. Bitmap Indexes

    位图索引的使用: 1.Bitmap indexing benefits data warehousing applications 2.Bitmap indexes are not suitable ...

  8. Oracle Hint 之 Parallel

    强制启用oralce的多线程处理功能. 并行查询允许将一个sql select 语句划分为多个较小的查询,每个部分的查询并发的运行,然后将各个部分的结果组合起来,提供最终的结果,多用于全表扫描,索引全 ...

  9. Oracle Parallel Execution(并行执行) .

    关于Oracle 的并行执行,Oracle 官方文档有详细的说明: Using Parallel Execution http://download.oracle.com/docs/cd/E11882 ...

最新文章

  1. Java 多线程编程之 notify notifyAll wait lock unlock 算法
  2. printf 中转义字符大全
  3. pytorch ShuffleNetV2 知识整理
  4. Python--unique()与nunique()函数
  5. javascript json_JavaScript 之 JSON.parse 导致大数精度丢失问题的解决方案
  6. [Angular 依赖注入详谈] Angular Module Providers几种类型的实现源代码具体位置
  7. hpuoj--校赛--与学妹滑雪(最短路+精度判断)
  8. 宇宙最強的IDE - Visual Studio 25岁生日快乐
  9. SpringBoot 中 4 大核心组件,你了解多少?
  10. BZOJ3238:[AHOI2013]差异——题解
  11. zabbix mysql.status_zabbix 监控mysql状态
  12. bzoj 3170: [Tjoi 2013]松鼠聚会
  13. CSS 控件适配器的菜单样式解释
  14. python获取a股报表数据_python获取A股基础数据
  15. 计算机术语多态意思,计算机外文翻译测试多态的关系的准则.doc
  16. FashionMNIST数据集国内可以用的下载地址
  17. 极大似然函数求解_极大似然估计法的理解指南
  18. 10.27 正睿提高9
  19. ubuntu18.04配置静态ip
  20. 聚类算法-K-means-C++实现

热门文章

  1. 红帽linux7注册,redhat7.2 解决注册问题 yum
  2. JVM有哪些类加载器?
  3. springboot中java泛型使用
  4. 主成分与因子分析异同_因子分析
  5. python中randn函数_numpy常用函数之randn
  6. 深入浅出 RecyclerView
  7. 苹果手机微信声音小怎么调大声_成都市苹果手机维修服务网点查询
  8. 计算机优化英语,英语对计算机专业的重要性及如何提高英语水平
  9. 利用mysql做信息管理_利用MySql实现学生信息管理系统的后台数据管理
  10. 添加cacti监控_小水谈监控---Cacti安装(监控)