深入学习SQL Server聚合函数算法优化技巧
作者:请叫我头头哥 发布时间:2024-01-23 20:36:14
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.3.T-sql语句查询时间:
4.4.占用内存:
4.5.T-sql语句查询IO:
关于监控元素还有很多,这里就列举几个。
SQL Server 聚合函数算法优化技巧差不多就介绍到这里,希望对大家优化聚合函数算法有所帮助。


猜你喜欢
- SQL Server管理,你做得好吗?下文这些可能会对你的工作有一些帮助,不妨耐心的看看吧。1. 数据库文件有.mdf .ndf .ldf三
- 在写 Node.js 应用程序的时候,你确实可以把所有代码放在巨大原 index.js 文件中,不在乎你的应用程序会变得多大多复杂。Node
- 先了解几个事件对象属性target 指事件源对象,点击嵌套元素最里层的某元素,该元素就是target。IE6/7/8对应的是srcEleme
- 本文实例为大家分享了python xlsxwriter创建excel图表的具体代码,供大家参考,具体内容如#coding=utf-8 imp
- 一.基本数据类型整数:int字符串:str(注:\t等于一个tab键)布尔值: bool列表:list 列表用[]元祖:tuple元祖用()
- 下文分步骤给大家介绍的非常详细,具体详情请看下文吧。一、准备用两台服务器做测试:Master Server: 192.0.0.1/Linux
- 需求描述:在公司老旧系统里,数据库表很多,但是在设计之初并没有建立好关系图,导致新人刚入职,面对N个库,每个库几百张表,很不方便。例如:公司
- pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。用 Echarts 生
- //继承function Person(name,sex){ this.name=name;
- 在安装好MYSQL ODBD的驱动程序后,应如何建立ASP文件连接数据库?我们有两种方法:一种是在ODBC数据源中建立一个DSN。具体方法是
- 目的:了解常用的ORM框架;使用SQLObject框架操作MySQL数据库。面试题:在Python语言中有哪些常用的ORM框架,它们有什么区
- 本文实例讲述了wxPython的事件驱动机制,分享给大家供大家参考。具体方法如下:先来看看如下代码:#!/usr/bin/python #
- 今天做了个基于PyQt4和PySide的输入对话框.已放到PyPi中,包名wlab,大家可以使用pip安装:pip install wlab
- 在做NLP(自然语言处理)相关任务时,经常会遇到需要识别并提取省、城市、行政区的需求。虽然我们自己通过关键词表一个个查找也能实现提取目的,但
- 窗外下着小雨,作为单身程序员的我逛着逛着发现一篇好东西,来自知乎 你都用 Python 来做什么?的第一个高亮答案。到上面去看了看,地址都是
- MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管
- Python当中并无switch语句,本文研究的主要是通过字典实现switch语句的功能,具体如下。switch语句用于编写多分支结构的程序
- 1、简要说明结巴分词支持三种分词模式,支持繁体字,支持自定义词典2、三种分词模式全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快
- 解决案例一:今天公司服务器上所有的网站都出现问题,有的打开没有数据,有的直接是空白。我的第一反应就是数据库挂了。打开远程,进了系统,serv
- 这里推荐使用OTK脚本安装Oracle,会大大提高安装Oracle的成功系数。DescriptionoraToolKit is the Sw