Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期。Sql server聚合函数对一组值执行计算并返回单一的值。聚合函数对一组值执行计算,并返回单个值。除了 COUNT 以外,聚合函数都会忽略空值。 聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用。

 

v1.写在前面

如果有对Sql server聚合函数不熟或者忘记了的可以看我之前的一片博客。sql server 基础教程

本文中所有数据演示都是用Microsoft官方示例数据库:Northwind,至于Northwind大家也可以在网上下载。至于下载方法MSDN已经有了详细的说明了,这里就不多说了。

v2.Sql server标量聚合

2.1.概念: 

在只包含聚合函数的 SELECT 语句列列表中指定的一种聚合函数(如 MIN()、MAX()、COUNT()、SUM() 或 AVG())。当列列表只包含聚合函数时,则结果集只具有一个行给出聚合值,该值由与 WHERE 子句谓词相匹配的源行计算得到。

2.2.探索标量聚合: 

我们先用Sql server的"包括实际的执行计划"来看看一个简单的流聚合COUNT()来看看表里数据所有的行数。

再通过SET SHOWPLAN_ALL ON(关于输出中包含的列更多信息可以在链接中查看)来看看有关语句执行情况的详细信息,并估计语句对资源的需求。

通过SET SHOWPLAN_ALL ON我们来看看COUNT()具体做了那些事情:

  • 索引扫描:扫描当前表的行数
  • 流计算:计算行数的数量
  • 计算标量:将流计算出来的结果转化为适当的类型。(因为索引扫描出来的结果是根据表中数据的大小决定的,如果表中数据很多的话,COUNT是int类型就会有问题,所以在最终返回的时候需要将默认类型(数值一般默认类型是Big)转成int类型。)
  • 小结:通过SET SHOWPLAN_ALL ON我们可以查看Sql server聚合函数在给我们呈现最终效果的时候,为这个效果做了些什么事情。

2.3.标量聚合优化技巧: 

我们通过两个比较简单的sql查询来看看他们的区别

SELECT COUNT(DISTINCT ShipCity) FROM Orders
SELECT COUNT(DISTINCT OrderID) FROM Orders

从上图中可以看到,其实这两个查询从语句上来说没什么太大的区别,但是为什么开销会不一样,一个是查询城市一个是查询订单号。这是因为其实DISTINCT对于OrderID查询来说,是没有什么意义的,因为OrderID是主键,是不会有重复的。而ShipCity是会有重复的,Sql server的去重机制在去重的时候,会有一个排序的过程。这个排序还是比较消耗资源的。

对于数据量比较大的表其实不是很建议对大表排序或者对大表的某个重复次数多的字段去重运算。所以我们这里可以对ShipCity进行优化一下。可以对ShipCity创建一个非聚集索引

CREATE INDEX Index_ShipCity On Orders(ShipCity desc)
go

从上图中可以看到,加了索引以后COUNT(DISTINCT ShipCity)的查询变成了两个流聚合,而没有了排序,节省了开销。

总结:对于标量聚合从上面的例子大家可以看到,标量聚合优缺点很明显:

  • Sql server标量聚合优点:算法比较简单直观,适合非重复值的聚合操作。
  • Sql server标量聚合缺点:性能较差(需要排序),不适合重复值的聚合操作。

优化技巧:

  • 尽量避免排序产生
  • 将分组字(GROUP BY)段锁定在索引覆盖范围内

v3.Sql server哈希聚合

3.1.概念: 

哈希(Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。)

哈希聚合的内部实现方法和哈希连接的实现机制一样,需要哈希函数的内部运算,形成不同的哈希值,依次并行扫描数据形成聚合值。

3.2.背景: 

为了解决流聚合的不足,应对大数据的操作,所以哈希聚合就诞生了。

3.3.分析: 

来看看两个简单的查询。

ShipCountry和CustomerID的分组查询看上去很类似,但是为什么执行计划会不同呢?这是因为ShipCountry包含了大量的重复值,CustomerID重复值非常少,所以Sql server系统给ShipCountry推送的哈希聚合,而CustomerID推送的是流聚合。也就是说Sql server系统会动态的根据查询的情况选择合适的聚合方式。所以我们在做SQL优化的时候不能仅根据SQL语句来优化,还得结合具体数据分布的环境。

v4.运算过程监控指标

4.1.监控元素: 

  • 可视化查看运行时间
  • T-sql语句查询时间
  • 占用内存
  • T-sql语句查询IO

4.2.可视化查看运行时间: 

4.3.T-sql语句查询时间: 

4.4.占用内存: 

4.5.T-sql语句查询IO: 

关于监控元素还有很多,这里就列举几个。

v博客总结

SQL Server 聚合函数算法优化技巧差不多就介绍到这里,如果有对sql语句优化感兴趣的可以看这篇博客。sql server之数据库语句优化

作  者:请叫我头头哥

出  处:http://www.cnblogs.com/toutou/

关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

SQL Server 聚合函数算法优化技巧的更多相关文章

  1. 数据库开发基础-SQl Server 聚合函数、数学函数、字符串函数、时间日期函数

    SQL 拥有很多可用于计数和计算的内建函数. 函数的语法 内建 SQL 函数的语法是: SELECT function(列) FROM 表 函数的类型 在 SQL 中,基本的函数类型和种类有若干种.函 ...

  2. sql server聚合函数sum计算出来为空,怎样返回0

    通常我们计算数据库中表的数据有几个常用的聚合函数 1.count : 计数 2.sum: 计算总和 3.avg: 取平均值 4.max: 取最大值 5.min: 取最小值 6.isnull: 当返回数 ...

  3. SQL Server聚合函数

    聚合函数对一组值计算后返回单个值.除了count(统计项数)函数以外,其他的聚合函数在计算式都会忽略空值(null).所有的聚合函数均为确定性函数.即任何时候使用一组相同的输入值调用聚合函数执行后的返 ...

  4. SQL Server聚合函数与聚合开窗函数 (转载)

    以下面这个表的数据作为示例. 什么是聚合函数?聚合函数:聚合函数就是对一组值进行计算后返回单个值(即分组).聚合函数在计算时都会忽略空值(null).所有的聚合函数均为确定性函数.即任何时候使用一组相 ...

  5. SQL Server聚合函数与聚合开窗函数

    以下面这个表的数据作为示例. 什么是聚合函数? 聚合函数:聚合函数就是对一组值进行计算后返回单个值(即分组).聚合函数在计算时都会忽略空值(null). 所有的聚合函数均为确定性函数.即任何时候使用一 ...

  6. SQL server聚合函数、数学函数、字符串函数

    一.基础语句 二.数学函数与字符串函数 三.练习 1.创建一个学生信息表,根据要求写出程序 2.新建一个超市表,进了十种商品,个数都是十件

  7. SQL Server日期函数之获得一个月中的天数

    SQL Server日期函数之获得一个月中的天数在实际中的应用比例还是占为多数的,如果你对这一技术,心存好奇的话,以下的文章将会揭开它的神秘面纱,望会在以后的学习或是工作中带来很大的帮助. 获得一个月 ...

  8. 13、SQL Server 自定义函数

    SQL Server 自定义函数 在SQL Server中不仅可以使用系统函数(如:聚合函数,字符串函数,时间日期函数等)还可以根据需要自定义函数. 自定义函数分为标量值函数和表值函数. 其中,标量值 ...

  9. SQL SERVER 2008- 字符串函数

    /* 1,ASCII返回字符表达式中最左侧字符的ASCII代码值 仅返回首字母的ASCII码值 parameter char或varchar returns integer */ SELECT ASC ...

随机推荐

  1. PHP中的魔术方法(2)

    1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ...

  2. chrome浏览器的跨域设置——包括版本49前后两种设置

    做前后分离的webapp开发的时候,出于一些原因往往需要将浏览器设置成支持跨域的模式,好在chrome浏览器就是支持可跨域的设置,网上也有很多chrome跨域设置教程.但是新版本的chrome浏览器提 ...

  3. linux源码分析(四)-start_kernel-cgroup

    前置:这里使用的linux版本是4.8,x86体系. cgroup_init_early(); 聊这个函数就需要先了解cgroup. cgroup概念 这个函数就是初始化cgroup所需要的参数的.c ...

  4. 用CSS3动画特效实现弹窗效果

    提示:如果大家觉得本篇实现的弹窗效果有用,可持续关注.接下会添加更多效果并且封装成插件,这样使用就方便了.效果查看: https://heavis.github.io/hidialog/index.h ...

  5. 使用css3新属性clip-path制作小图标

    一般一个网页上面,或多或少都会用到一些小图标,展示这些小图标的方法有很多种.最简单的做法就是将UI图上面的每个小图标都保存为图片,一个小图标就一张图片.但这也是比较笨的方法,因为浏览器同一时间最多加载 ...

  6. C#基础知识四之override和new的区别

    override override是派生类用来重写基类方法的.调用的派生类方法,如需调用基类方法用base关键字 override不能重写非虚方法或静态方法. override重写必须用abstrac ...

  7. .NET跨平台之Sake和KoreBuild

    最近在了解Asp.net Core 1.0(也可称为Asp.net5\Asp.net vNext)的跨平台,发现了两个新的新东西:Sake和KoreBuild(或者已经出了很久). 通过国内某度查询资 ...

  8. oracle函数大全(转载)

    F.1字符函数--返回字符值 这些函数全都接收的是字符族类型的参数(CHR除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据 ...

  9. 【C语言学习趣事】_33_关于C语言和C++语言中的取余数(求模)的计算_有符号和无符号数的相互转换问题

    最近再次复习C++语言,用的教材是<C++ Primer>这本教材, 看到第二章的时候,里面有个问题困扰了我. 于是想上网查查怎么回事, 结果看了很久都没有得到一个满意的答案. 书上有这么 ...

  10. 数据结构:链表(python版)

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Author: Minion Xu class LinkedListUnderflow(ValueErro ...