接上文:SQL Server 执行计划操作符详解(2)——串联(Concatenation )

前言:


前面两篇文章介绍了关于串联(Concatenation)断言(Assert)操作符,本文介绍第三个常见的操作符计算标量(Compute Scalar)。这个操作符的名字比较直观——进行一个标量计算并返回计算值。官方说明:Compute Scalar 运算符通过对表达式求值来生成计算标量值。该值可以返回给用户、在查询中的其他位置引用或二者皆可。例如,在筛选谓词或联接谓词中就会出现二者皆可的情况。
该操作符的图标为:,它既是一个逻辑操作符,也是一个物理操作符。这个操作符可能不容易引起用户注意,因为一般我们看执行计划是因为语句有问题,而有问题的语句又通常是比较复杂或混乱的,这些语句生成的执行计划往往也非常复杂。相对于整个执行计划来说,这个操作符通常是比较小开销的。
但是这个操作符之所以重要或常见,是因为它通常是由于游标处理或其他一些大范围查找引起的,这些操作可能在CPU存在压力时变得雪上加霜。

演示:


使用TempDB做测试是一个不错的选择,简单重启一下SQL 服务即可清空过去的操作,不过如果你发现重启后还在,那不妨检查一下是否建到Model数据库或者设置为启动时运行。下面代码在TempDB中创建一个表,插入10000行数据后,循环100次进行数据检查:

USE tempdb
GO
CREATE TABLE test(ID   Int Identity(1,1) PRIMARY KEY,
                Name VarChar(250)  DEFAULT NewID())
GO
SET NOCOUNT ON
GO
INSERT INTO test DEFAULT VALUES
GO 10000  --循环插入10000行数据

GO
--下面代码循环100次,判断是否存在某个ID
DECLARE @I Int
SET @I = 0
WHILE @I < 100
BEGIN
  IF EXISTS(SELECT ID FROM test WHERE ID = @I)
  BEGIN
    PRINT '存在这个ID'
  END
  SET @I = @I + 1;
END
GO

看一下图形化执行计划:




截图中红框部分表明使用了计算标量操作符,使用前面的方法,检查文本化执行计划:

SET SHOWPLAN_TEXT ON
GO
DECLARE @I Int
SET @I = 0
WHILE @I < 100
BEGIN
  IF EXISTS(SELECT ID FROM test WHERE ID = @I)
  BEGIN
    PRINT '存在这个ID'
  END
  SET @I = @I + 1;
END


可以看到执行计划使用计算标量操作符来检查嵌套循环(Nested Loop)是否返回了值,也就是说用于实现IF EXISTS操作。

如果使用Profiler来抓取信息,记住一下CPU开销:



下面改写一下语句来避免这个操作符:

DECLARE @I Int, @Var Int
SET @I = 0
WHILE @I < 100
BEGIN
  SELECT @Var = ID FROM test WHERE ID = @I
  IF @@ROWCOUNT > 0
  BEGIN
    PRINT '存在这个ID'
  END
  SET @I = @I + 1;
END
GO

再看看图形化执行计划:




及Profiler信息:




如果再检查文本化执行计划就可以看到只有一个操作符:

       |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[test].[PK__test__3214EC27D8827737]), SEEK:([tempdb].[dbo].[test].[ID]=[@I]) ORDERED FORWARD)

对比Profiler中的数据,没有使用计算标量的执行计划消耗更少的CPU和运行时间去完成结果,这里主要是演示计算标量,所以不对写法做更深入的研究。但是从写法上看,使用了@@rowcount函数替代IF EXISTS,有时候会有一定的帮助,当然,并不是绝对的。


如果你觉得是数据量的原因,不妨再看看下面的脚本:

DECLARE @Tab TABLE(ID SmallInt PRIMARY KEY)
SELECT 'A' + ' - ' + 'B' FROM @Tab

然后看看图形化执行计划:




和文本化执行计划:

  |--Compute Scalar(DEFINE:([Expr1002]='A - B'))
       |--Clustered Index Scan(OBJECT:(@Tab))

这个语句只是简单地进行字符串拼接,但是也使用了计算标量运算符,原因可以查看执行计划的解释:





总结:

正如一直以来的解释,每个操作符的出现都有其原因和作用,并不能简单地下定论这个操作符是好还是坏,但是某些操作符确实意味着性能问题,所以如果精力允许,也应该对常见的操作符进行一定程度的研究。当发现某个低效查询中出现这个操作符时,不妨想想其原因,并尝试是否能进行优化,优化的原则则是根据其含义而定,既然这个操作符是根据现有值计算新值,那么我们的核心方案应该是减少这种操作的数据量或者预先计算新值。总的而言,具体情况具体分析。
下一篇将介绍一个更为常见并且通常意味着有优化空间的操作符:键查找:Key Lookup   

SQL Server 执行计划操作符详解(3)——计算标量(Compute Scalar)的更多相关文章

  1. SQL Server 执行计划操作符详解(2)——串联(Concatenation )

    本文接上文:SQL Server 执行计划操作符详解(1)--断言(Assert) 前言: 根据计划,本文开始讲述另外一个操作符串联(Concatenation),读者可以根据这个词(中英文均可)先幻 ...

  2. SQL Server 执行计划操作符详解(1)——断言(Assert)

    前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很 ...

  3. 学习如何看懂SQL Server执行计划(二)——函数计算篇

    二.函数计算部分 --------------------标量聚合--------------------/* 标量聚合-主要在聚合函数操作中产生 计算标量:根据行中的现有值计算出一个新值 流聚合:在 ...

  4. MySQL 执行计划explain详解

    MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但 ...

  5. SQL Server 执行计划缓存

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/内存池/缓冲区 概述 了解执行计划对数据库性能分析很重要,其中涉及到了语句性能分析与存储,这也是写这篇文章的目的,在了解执行计划之 ...

  6. sql server 执行计划(execution plan)介绍

    大纲:目的介绍sql server 中执行计划的大致使用,当遇到查询性能瓶颈时,可以发挥用处,而且带有比较详细的学习文档和计划,阅读者可以按照我计划进行,从而达到对执行计划一个比较系统的学习. 什么是 ...

  7. SQL Server 执行计划中的扫描方式举例说明

    SQL Server 执行计划中的扫描方式举例说明 原文地址:http://www.cnblogs.com/zihunqingxin/p/3201155.html 1.执行计划使用方式 选中需要执行的 ...

  8. SQL Server执行计划那些事儿(3)——书签查找

    接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. ...

  9. SQL Server执行计划那些事儿(2)——查找和扫描

    接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. ...

随机推荐

  1. [TJOI 2013]单词

    Description 题库链接 给出一篇文章的所有单词,询问每个单词出现的次数. 单词总长 \(\leq 10^6\) Solution 算是 \(AC\) 自动机的板子,注意拼成文章的时候要在单词 ...

  2. [ZJOI 2006]物流运输

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  3. [SHOI2008]小约翰的游戏John

    Description 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取 的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不 ...

  4. bzoj 5251: [2018多省省队联测]劈配

    Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ...

  5. 基于Android的高校饮水宝app

     这是一个高校饮用水配送项目,是一个毕业设计,去年的,包括了服务端和客户端,是一个不错的项目,分享一下: 随着通讯行业的迅猛发展,我国的手机用户也在不断的增加.据信息部的统计数据显示,我国已有接近7. ...

  6. Go实现海量日志收集系统(三)

    再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...

  7. 修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法

    在SQL数据库中使用SQL语句(格式:alter table [tablename] alter column [colname] [newDataType])修改某表的字段类型时,报一下错误:由于一 ...

  8. Python中模块之sys的功能介绍

    sys模块的功能介绍 1. sys的变量 argv 命令行参数 方法:sys.argv 返回值:list 例如:test1.py文件中有两句语句1.import sys 2.print(sys.arg ...

  9. PHP+JQuery+Ajax初始化网站基本信息(附源码)--PHP

    一.思路 为了保存用户会员信息的时间长一些,不局限于session的关闭.我们需要将用户信息保存在数据库中,前台每次登录都需要进行校验,来查看用看用户会员信息是否过期,如果没有过期,取出用户会员信息存 ...

  10. Windows笔记目录

    Windows笔记目录   Windows介绍 Windows入门--个人感想 初入Linux AD域控 FTP 服务器及权限 Server-U FTP与AD完美集成方案详解 其他 Linux大文件传 ...