侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

深入学习SQL Server聚合函数算法优化技巧

数据库  /  管理员 发布于 5年前   222

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

一.写在前面

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

本文中所有数据演示都是用Microsoft官方示例数据库:Northwind,至于Northwind大家也可以在网上下载。

二.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 OrdersSELECT 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)段锁定在索引覆盖范围内

三.Sql server哈希聚合

3.1.概念:

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

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

3.2.背景:

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

3.3.分析:

来看看两个简单的查询。

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

四.运算过程监控指标

4.1.监控元素:

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

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

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

4.4.占用内存:

4.5.T-sql语句查询IO:

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

SQL Server 聚合函数算法优化技巧差不多就介绍到这里,希望对大家优化聚合函数算法有所帮助。


  • 上一条:
    SqlServer应用之sys.dm_os_waiting_tasks 引发的疑问(上)
    下一条:
    SQLServer中Partition By及row_number 函数使用详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客