zoukankan      html  css  js  c++  java
  • SQL Server 2005技术内幕:查询、调整和优化4——聚合

    对于聚合,SQL Server支持两种物理操作符:流聚合与哈希聚合。

    标量聚合

    标量聚合通过在选择列表中没有GROUP BY语句的聚合函数查询。标量聚合总是返回一个单一的行。SQL Server总是使用流聚合操作符实现标量聚合。

    下面是个简单的例子:

     

    select COUNT(*from [Orders]

     

    这个查询产生下面的计划:

    流聚合操作符就是计算输入行的大小并返回结果。流聚合实际计算Bigint的总数([Expro1004])。计算的数量需要把这个结果转换成期待的Int型。注意到标量流聚合是一个没有页节点操作符例子中的一个,可以在空输入集时产生一个输入。

     

    如何实现其他的简单标量聚合函数,例如MINMAXSUM。一个单一流聚合操作符可以在同一时刻计算多个标量聚合。

     

    select MIN(Orderdate), MAX(orderdate) from [Orders]

     

    下面是使用单一流聚合操作符的查询计划:

    注意到SQL Server不需要对MINMAX集合转换结果,因为这些集合是基于订单日期列数据类型计算的。

    一些集合,例如AVG实际上是从其他两个集合如SUMCOUNT中计算的:

     

    select AVG(Freight) from [orders]

     

    请注意计划中的计算标量操作符是如何从sumcount中计算平均值的:

     

    CASE表达式是必须的,用以确定SQL Server不会试图被零整除。

            

    select SUM(Freight) from [orders]

            

       尽管本质上SUM不需要计算,但仍然要进行计数:

             以下这个查询计划中的CASE表达式如果应用COUNT来确保SUM在没有行时返回NULL,而不是零。

     

    Scalar Distinct

             如果对标量聚合添加DISTINCT关键字进行查询,计算以运送的订单的不同城市的数量,查询如下:

     

    select COUNT(distinct [shipcity]from [orders]

    以上查询产生的查询计划如下:

    因为查询必须对那些ShipCity列上有唯一值的行计算,SQL Server 增加显示排序操作符消除ShipCity上的重复值,显示排序是SQL Server用来消除排序重复行的常见方法之一。在对输入集进行排序后就很容易去除重复的行,因为重复的行和另外一个行是邻接的。

     

    多个 Distinct

    select COUNT(distinct [shipaddress]), COUNT(distinct[shipcity]

       
    from [orders]

     

    SQL Server可以通过消除ShipAddress列上重复值的行来计算COUNTDISTINCT[ShipAddress])。类似的,SQL Server可以通过消除ShipCity列上的重复值来计算COUNTDISTINCT[ShipTity])。但是,假设给出的这两个行的集合不同,SQL Server如果同时对这两个行进行计算,SQL Server做不到,它必须先计算一个聚合的结果,然后计算另一个,再把这两个结果合并成一个单一的输出:

     

    嵌套循环连接的两个输入从原始的查询中计算两个数量,其中一个输入去掉重复的,计算ShipAddress列的数量,另一个输入去掉重复的,计算ShipCity列的数量。嵌套循环连接没有连接谓词,它是交叉连接。因为嵌套循环连接的两个输入每一个产生单一的行,且它们的标量集合-交叉连接的结果也会一个单一的行。交叉连接就是把结果的两行“粘贴”为单一的行。

     

    流聚合

     

    算法         流聚合依赖与获得存储在GROUP BY列中的数据。如同合并连接,如果一个查询包含GROUP BY语句多于一行,流聚合会使用任何包含所有行的排序次序。例如,流聚合会对Col1列和Col2列分组,而数据存储在(Col1Col2)或(Col2Col1)上。与合并连接类似,排序次序也会被一个索引或一个显示排序操作符影响。排序次序将确保列GROUP BY有着相同值的行集合彼此相连。

    例如,为了计算SUM,流聚合会考虑每个输入行。如果输入行属于目前的组(输入行的group by列和以前行的group by列是匹配的),则流聚合可通过从输入行中增加合适的值来更新目前的SUM。如果输入的行属于一个新的组(输入的行group by列和以前行的group by列不匹配),流聚合会输出目前的SUM,把SUM设为零,开始新的组。

    简单示例  下面的查询将计算对于每个地址运送订单的数量:

    select [ShipAddress][ShipCity]COUNT(*)

    From [Orders] group by [ShipAddress][ShipCity]

     

    下面是这个查询的计划:

     

    除了SQL Server在聚合前需要对数据排序外,这个计划和之前看到的标量聚合的查询基础一样,可以认为标量聚合是一个包含所有行的一个大组,因此,对于一个标量聚合,没有必要将行排序为不同的组。(未完待续)

  • 相关阅读:
    jQuery EasyUI API 中文文档 数字框(NumberBox)
    jQuery EasyUI API 中文文档 数值微调器(NumberSpinner)
    jQuery EasyUI API 中文文档 日期时间框(DateTimeBox)
    jQuery EasyUI API 中文文档 微调器(Spinner)
    jQuery EasyUI API 中文文档 树表格(TreeGrid)
    jQuery EasyUI API 中文文档 树(Tree)
    jQuery EasyUI API 中文文档 属性表格(PropertyGrid)
    EntityFramework 数据操作
    jQuery EasyUI API 中文文档 对话框(Dialog)
    jQuery EasyUI API 中文文档 组合表格(ComboGrid)
  • 原文地址:https://www.cnblogs.com/fengxiang/p/1816078.html
Copyright © 2011-2022 走看看