位置: 编程技术 - 正文

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)

  • 车船税规定怎么缴纳
  • 城建税 小规模
  • 没有支付运费会怎样
  • 个人开具发票需要税号吗
  • 在建工程明细账采用什么账簿
  • 企业转让无形资产使用权取得的收入应计入营业外收入
  • 个人因终止投资经营而取得的股权转让收入如何计算个人所得税?
  • 证券交易印花税是多少
  • 收取员工宿舍租金收入要交增值税吗
  • 小规模纳税人普票超过30万怎么交税
  • 营业外收入做多了怎么办
  • 通行费发票如何开具
  • 营改增后发票报销管理规定是怎样的?
  • 建筑行业预收账款
  • 银行贷款的纳税申报表指的所得税还是增值税
  • 报废车辆补贴收据怎么写
  • 工程发票需要进项吗
  • 暂估入库库存出现负数怎么办?
  • 母公司向全资子公司划转土地
  • 增值税申报错误已经扣税怎么处理
  • 合作社人工工资账务处理
  • phpjson
  • 个体户年报如何公示
  • Win11 Build 22000.348更新补丁KB5007262预览版发布(附更新修复内容汇总)
  • 巴伐利亚州地图
  • findfont: Font family [‘Times New Roman‘] not found. Falling back to DejaVu Sans.
  • 现金日记账的填制要求
  • 房抵债权
  • 固定资产减值准备可以转回吗
  • html+css登录页面
  • 我已经用尽了洪荒之力漫画表情
  • 为什么说网络安全靠人民
  • python random random
  • 员工奖励现金如何做账
  • 电子回单是什么样子
  • 电子商务公司怎么做账比较合适
  • 发票普票增票
  • 一般纳税企业增值税的核算应当使用
  • 哪些情况不能开专用发票
  • 房产税是按不含增值税计提吗
  • 小企业长期债券投资
  • 非营利组织增值税怎么处理
  • 即征即退增值税需要缴纳所得税吗
  • 小规模免征增值税的会计处理办法
  • 收到退回的增值税,应当作为营业外收入核算对吗
  • 发票系统怎么用
  • 开具电费发票如何入账?
  • 开具红字发票后所冲销的销项税应该怎么处理?
  • 广告设计合同属于什么合同
  • 试生产期间的收入如何做账
  • 其他应收款为负数正常吗
  • 法人投资属于什么会计科目
  • 冲销销售收入分录
  • 其他债权投资发生减值会影响所有者权益总额吗
  • 接受其他企业现金捐赠会计分录
  • 土地使用权使用年限怎么算
  • 税收返还如何做账
  • 广州残保金如何计算
  • 建账需要买哪些会计用品
  • sqlserver数据库中的null值空值表示的是空格或零值
  • 无法打开vmx86
  • w10怎么usb连接上网
  • cocos2dx游戏开发框架
  • Unity3D游戏开发标准教程吴亚峰于复兴人民邮电出版社
  • 用户允许控制
  • vue stylus
  • centos创建shell脚本
  • python字符串大全
  • unity closestpoint
  • rsa 密钥格式
  • js 原型方法
  • 安卓listview添加数据
  • 快速掌握英语的方法
  • 河南省地方税务局公告2017年第4号
  • 应税消费品通过什么科目核算
  • 税务清单模板
  • 企业所得税改革
  • 军工企业销售模式
  • 商铺收税多少
  • 2022年广州社保基数
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设