位置: 编程技术 - 正文

SQL Server中的执行引擎入门 图解(sql server 执行语句)

编辑:rootadmin
本文旨在分类讲述执行计划中每一种操作的相关信息。

数据访问操作

首先最基本的操作就是访问数据。这既可以通过直接访问表,也可以通过访问索引来进行。表内数据的组织方式分为堆(Heap)和B树,其中表中没有建立聚集索引时数据是通过堆进行组织的,这个是无序的,表中建立聚集索引后和非聚集索引的数据都是以B树方式进行组织,这种方式数据是有序存储的。通常来说,非聚集索引仅仅包含整个表的部分列,对于过滤索引,还仅仅包含部分行。

除去数据的组织方式不同外,访问数据也分为两种方式,扫描(Scan)和查找(Seek),扫描是扫描整个结构的所有数据,而查找只是查找整个结构中的部分数据。因此可以看出,由于堆是无序的,所以不可能在堆上面进行查找(Seek)操作,而相对于B树的有序,使得在B树中进行查找成为可能。当针对一个以堆组织的表进行数据访问时,就会进行堆扫描,如图1所示。

图1.表扫描

可以看出,表扫描的图标很清晰的表明表扫描的性质,在一个无序组织表中从头到尾扫描一遍。

而对于B树结构的聚集索引和非聚集索引,同样可以进行扫描,通常来讲,为了获取索引表中的所有数据或是获得索引行树占了数据大多数使得扫描的成本小于查找时,会进行聚集索引扫描。如图2所示。

图2.聚集索引扫描

聚集索引扫描的图标也同样能够清晰的表明聚集索引扫描的性质,找到最左边的叶子节点后,依次扫描所有叶子节点,达到扫描整个结构的作用。当然对于非聚集索引也是同样的概念,如图3所示。

图3.非聚集索引的扫描

而对于仅仅选择B树结构中的部分数据,索引查找(Seek)使得B树变得有意义。根据所查找的关键值,可以使得从仅仅从B树根部向下走单一路径,因此免去了扫描不必要页的消耗,图4是查询计划中的一个索引查找。

图4.聚集索引查找

索引查找的图标也是很传神的,可以看到图标那根线从根节点一路向下到叶子节点。也就是找到所求数据所在的页,不难看出,如果我们需要查找多条数据且分散在不同的页中,这个查找操作需要重复执行很多回,当这个次数大到一定程度时,SQL Server会选择消耗比较低的索引扫描而不是再去重复索引查找。对于非聚集索引查找,概念是一样的,就不再上图片了。

书签查找(Bookmark Lookup)

你也许会想,假如非聚集索引可以快速的找到所求的数据,但遗憾的是,非聚集索引却不包含所有所求列时该怎么办?这时SQL Server会面临两个选择,直接访问基本表去获取数据或是在非聚集索引中找到数据后,再去基本表获得非聚集索引没有覆盖到的所求列。这个选择取决于所估计的行数等统计信息。查询分析器会选择消耗比较少的那个。

一个简单的书签查找如图5所示。

图5.一个简单的书签查找

从图5可以看出,首先通过非聚集索引找到所求的行,但这个索引并不包含所有的列,因此还要额外去基本表中找到这些列,因此要进行键查找,如果基本表是以堆进行组织的,那么这个键查找(Key Lookup)就会变成RID查找(RID Lookup),键查找和RID查找统称为书签查找。

不过有时候索引查找所返回的行数过多导致书签查找的性能远不如直接进行扫描操作,因此SQL Server这时会选择扫描而不是书签查找。如图6所示。

图6.StateProvinceID列有非聚集索引,但由于返回行数过多,分析器会选择扫描而不是书签查找

这个估计是根据统计信息进行的,关于统计信息,可以看我之前的一篇博文:浅谈SQL Server中统计对于查询的影响

聚合操作(Aggregation)

聚合函数会导致聚合操作。聚合函数是将一个集合的数据按照某种规则汇总成1个数据,或基于分组按照规则汇总成多个数据的过程。一些聚合函数比如:avg,sum,min,另外还有distinct关键字都有可能导致两类聚合操作:流聚合(Stream Aggregation)和哈希聚合(Hash Aggregation)。

流聚合(Stream Aggregation)

流聚合需要再执行聚合函数之前,被聚合的数据集合是有序的,这个有序数据既可以通过执行计划中的Sort进行,也可以直接从聚集或是非聚集索引中直接获得有序数据,另外,没有Group by的聚合操作被成为标量聚合,这类操作一定是会执行流聚合。

比如,我们直接进行标量聚合,如图7所示。

图7.流聚合

但对于加了Group by的子句,因为需要数据按照group by 后面的列有序,就需要Sort来保证排序。注意,Sort操作是占用内存的操作,当内存不足时还会去占用tempdb。SQL Server总是会在Sort操作和散列匹配中选择成本最低的。一个需要Sort的操作如图8所示。

图8.需要排序的流聚合

图8中排序操作按照ProductLine进行排序后,然后就根据各自的分组做聚合操作了。

散列聚合(Hash aggregation)

上面的流聚合适合比较少的数据,但是对于相对大一点的表。使用散列集合成本会比排序要低。散列集合通过在内存中建立散列表来实现聚合,因此无需对数据集合进行排序。内存中所建立的散列表以Group by后面的列作为键值,如图9所示。

图9.散列聚合

在内存中建立好散列表后,会按照group by后面的值作为键,然后依次处理集合中的每条数据,当键在散列表中不存在时,向散列表添加条目,当键已经在散列表中存在时,按照规则(规则是聚合函数,比如Sum,avg什么的)计算散列表中的值(Value)。

连接(Join)

当多表连接时(书签查找,索引之间的连接都算),SQL Server会采用三类不同的连接方式:循环嵌套连接(Nested Loops Join),合并连接(Merge Join),散列连接(Hash Join)。这几种连接并不是哪种会比另一种更好,而是每种连接方式都会适应特定场景。

循环嵌套连接(Nested Loops Join)

由图可以看到一个简单的循环嵌套连接。

图.一个循环嵌套连接的实例

循环嵌套连接的图标同样十分传神,处在上面的外部输入(Outer input),这里也就是聚集索引扫描。和处在下面的内部输入(Inner Input),这里也就是聚集索引查找。外部输入仅仅执行一次,根据外部输入满足Join条件的每一行,对内部输入进行查找。这里由于是行,对于内部输入执行次。

可以通过属性窗口看到.如图所示:

图.内部输入的执行次数

根据嵌套循环的原理不难看出,由于外部输入是扫描,内部输入是查找,当两个Join的表外部输入结果集比较小,而内部输入所查找的表非常大时,查询优化器更倾向于选择循环嵌套方式。

合并连接(Merge Join)

不同于循环嵌套的是,合并连接是从每个表仅仅执行一次访问。从这个原理来看,合并连接要比循环嵌套要快了不少。下面来看一个典型的合并连接,如图所示。

图.合并连接

从合并连接的原理不难想象,首先合并连接需要双方有序.并且要求Join的条件为等于号。因为两个输入条件已经有序,所以从每一个输入集合中取一行进行比较,相等的返回,不相等的舍弃,从这里也不难看出Merge join为什么只允许Join后面是等于号。从图的图标中我们可以看出这个原理。

如果输入数据的双方无序,则查询分析器不会选择合并连接,我们也可以通过索引提示强制使用合并连接,为了达到这一目的,执行计划必须加上一个排序步骤来实现有序,如图所示。

图.通过排序来实现Merge Join

散列连接(Hash Join)

散列连接同样仅仅只需要只访问1次双方的数据。散列连接通过在内存中建立散列表实现。这比较消耗内存,如果内存不足还会占用tempdb。但并不像合并连接那样需要双方有序。一个典型的散列连接如图所示。

图.散列连接

这里我删除了Costomer的聚集索引,否则两个有序输入SQL Server会选择代价更低的合并连接。SQL Server利用两个上面的输入生成哈希表,下面的输入来探测,可以在属性窗口看到这些信息,如图所示。

图.散列键生成和散列键探测

通常来说,在两个输入数据比较大,且所求数据在其中一方或双方没有排序的条件达成时,会选用散列匹配。

并行

当多个表连接时,SQL Server还允许在多CPU或多核的情况下允许查询并行,这样无疑提高了效率,一个并行的例子如图所示。

图.并行提高效率

总结

本文简单介绍了SQL Server执行计划中常见的操作极其原理,了解这些步骤和原理是优化查询的基本功。

推荐整理分享SQL Server中的执行引擎入门 图解(sql server 执行语句),希望有所帮助,仅作参考,欢迎阅读内容。

SQL Server中的执行引擎入门 图解(sql server 执行语句)

文章相关热门搜索词:sql执行数据,sql server 执行语句,sqlserver2008r2执行语句,sqlserver2008r2执行语句,sql server执行,sql server 执行语句,sql server执行,sql server执行,内容如对您有帮助,希望把文章链接给更多的朋友!

浅谈SQL Server中统计对于查询的影响分析 而每次查询分析器寻找路径时,并不会每一次都去统计索引中包含的行数,值的范围等,而是根据一定条件创建和更新这些信息后保存到数据库中,这

用SQL统计SQLServe表存储空间大小的代码 其实SQLServer提供了一个sp_spaceused的系统存储过程可以实现该功能,下面就是调用的SQL:createtable#tb(表名sysname,记录数int,保留空间varchar(),使用空间varchar(

ROW_NUMBER SQL Server 的LIMIT功能实现(ROW_NUMBER()排序函数) 语法:ROW_NUMBER()OVER([partition_by_clause]order_by_clause)备注:ORDERBY子句可确定在特定分区中为行分配唯一ROW_NUMBER的顺序。参数:partition_by_clause将FROM子句生成

标签: sql server 执行语句

本文链接地址:https://www.jiuchutong.com/biancheng/348553.html 转载请保留说明!

上一篇:分析SQL语句性能3种方法分享(分析sql语句性能实现)

下一篇:浅谈SQL Server中统计对于查询的影响分析(sql server的go)

  • 固定资产未转固属于什么风险
  • 代开运输发票会不会造成重复征税
  • 建筑业增值税税率2022
  • 在建工程贷款利息分录
  • 出口资质需要哪些资质
  • 售后回租利息可以抵税吗
  • 发票认证后怎么打明细
  • 软件工程质保金
  • 设备售后回租需交税吗
  • 职工工资保险费账务处理怎么做?
  • 公司会计怎么做
  • 货运代理公司排名前十
  • 房地产预缴土地增值税的账务处理
  • 部队收礼怎么处罚
  • 计提未发放的工资是否交个税
  • 地税有哪些税种类型
  • 增值税的会计核算
  • 失控发票进项税额转出申报表填写
  • 购物卡开预付卡有风险吗
  • 工会经费申报表的应税项应该怎样填写
  • 培训机构的收入有哪几方面
  • 社保稽查补社保按什么基数来
  • 购买办公用品发放给各部门使用
  • 农产品成本法计算抵扣
  • php发送电子邮件
  • 如何在局域网内发布网页
  • 研发费用加计扣除是什么意思啊
  • 后端接口返回数据类型规范
  • 软件工程毕设题目冷门
  • 固定资产残料收税吗
  • 微信小程序前端源码
  • php文件用什么运行
  • 土地使用税缴纳人是使用者还是所有权人
  • 金融商品转让业务包括
  • 工会筹备金计税依据
  • php获取浏览器ua
  • 经典动画动漫
  • 【历史上的今天】3 月 29 日:“机器人三定律”问世;电脑动画首次获得奥斯卡;Caldera Linux 沉浮史
  • 代收水电费交税吗
  • 消费税购置税价格一样
  • 中小型科技企业所面临的普遍问题是资金缺乏
  • 社保滞纳金计入个人账户吗
  • 退回的个税手续费计入什么科目
  • 发票跟税有什么关系
  • 帝国cms灵动标签调用外表
  • 补贴,津贴是否合理
  • sql优化的方法及思路
  • 固定资产折旧的计算方法
  • 通信服务费账务处理流程
  • 月底资产负债表怎么填
  • 有限公司股东撤资退股
  • 委托代理进出口
  • 税金及附加如何预测
  • 开发票四舍五入
  • 年中未分配利润
  • 房地产预售款预交税金计算
  • 制造企业费用会计
  • 运杂费计入什么会计科目
  • 公司没开户需要做账吗怎么做
  • 实现分页功能的多种原理方案
  • mac版安装教程
  • grub rescue修复引导找不到grub
  • linux如何拨号
  • xp管理员账号密码
  • GhostXP装机版v3.0
  • 在linux系统中命令
  • windows7不显示移动硬盘
  • three.js加载glb文件
  • echarts怎么样
  • Android自定义对话框
  • opengl visual studio
  • xml文件示例
  • php编译安装常见的软件
  • javascript的核心语言对象包括
  • 如何理解vue
  • 深入理解javascript特性
  • python的设置
  • jquery 动态添加元素
  • python中tcp
  • 武汉市江岸区工商局咨询电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设