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

前言:

前面两篇文章介绍了关于串联(Concatenation)断言(Assert)操作符,本文介绍第三个常见的操作符计算标量(Compute Scalar)。这个操作符的名字比較直观——进行一个标量计算并返回计算值。

官方说明:Compute Scalar 运算符通过对表达式求值来生成计算标量值。该值能够返回给用户、在查询中的其它位置引用或二者皆可。比如。在筛选谓词或联接谓词中就会出现二者皆可的情况。

该操作符的图标为:,它既是一个逻辑操作符。也是一个物理操作符。这个操作符可能不easy引起用户注意,由于一般我们看运行计划是由于语句有问题,而有问题的语句又一般是比較复杂或混乱的,这些语句生成的运行计划往往也很复杂。相对于整个运行计划来说,这个操作符一般是比較小开销的。
可是这个操作符之所以重要或常见,是由于它一般是由于游标处理或其它一些大范围查找引起的。这些操作可能在CPU存在压力时变得雪上加霜。

演示:

使用TempDB做測试是一个不错的选择。简单重新启动一下SQL 服务就可以清空过去的操作。只是假设你发现重新启动后还在,那最好还是检查一下是否建到Model数据库或者设置为启动时运行。

以下代码在TempDB中创建一个表,插入10000行数据后,循环100次进行数据检查:

  1. USE tempdb
  2. GO
  3. CREATE TABLE test(ID Int Identity(1,1) PRIMARY KEY,
  4. Name VarChar(250) DEFAULT NewID())
  5. GO
  6. SET NOCOUNT ON
  7. GO
  8. INSERT INTO test DEFAULT VALUES
  9. GO 10000 --循环插入10000行数据
  10.  
  11. GO
  12. --以下代码循环100次,推断是否存在某个ID
  13. DECLARE @I Int
  14. SET @I = 0
  15. WHILE @I < 100
  16. BEGIN
  17. IF EXISTS(SELECT ID FROM test WHERE ID = @I)
  18. BEGIN
  19. PRINT '存在这个ID'
  20. END
  21. SET @I = @I + 1;
  22. END
  23. GO
看一下图形化运行计划:
截图中红框部分表明使用了计算标量操作符,使用前面的方法。检查文本化运行计划:
  1. SET SHOWPLAN_TEXT ON
  2. GO
  3. DECLARE @I Int
  4. SET @I = 0
  5. WHILE @I < 100
  6. BEGIN
  7. IF EXISTS(SELECT ID FROM test WHERE ID = @I)
  8. BEGIN
  9. PRINT '存在这个ID'
  10. END
  11. SET @I = @I + 1;
  12. END

能够看到运行计划使用计算标量操作符来检查嵌套循环(Nested Loop)是否返回了值。也就是说用于实现IF EXISTS操作。
假设使用Profiler来抓取信息,记住一下CPU开销:
以下改写一下语句来避免这个操作符:
  1. DECLARE @I Int, @Var Int
  2. SET @I = 0
  3. WHILE @I < 100
  4. BEGIN
  5. SELECT @Var = ID FROM test WHERE ID = @I
  6. IF @@ROWCOUNT > 0
  7. BEGIN
  8. PRINT '存在这个ID'
  9. END
  10. SET @I = @I + 1;
  11. END
  12. GO

再看看图形化运行计划:

及Profiler信息:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

假设再检查文本化运行计划就能够看到仅仅有一个操作符:
  1. |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[test].[PK__test__3214EC27D8827737]), SEEK:([tempdb].[dbo].[test].[ID]=[@I]) ORDERED FORWARD)

对照Profiler中的数据,没有使用计算标量的运行计划消耗更少的CPU和运行时间去完毕结果。这里主要是演示计算标量,所以不正确写法做更深入的研究。

可是从写法上看,使用了@@rowcount函数替代IF EXISTS,有时候会有一定的帮助。当然,并非绝对的。

假设你认为是数据量的原因,最好还是再看看以下的脚本:
  1. DECLARE @Tab TABLE(ID SmallInt PRIMARY KEY)
  2. SELECT 'A' + ' - ' + 'B' FROM @Tab

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

和文本化运行计划:
  1. |--Compute Scalar(DEFINE:([Expr1002]='A - B'))
  2. |--Clustered Index Scan(OBJECT:(@Tab))

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

总结:

正如一直以来的解释,每一个操作符的出现都有其原因和作用,并不能简单地下定论这个操作符是好还是坏。可是某些操作符确实意味着性能问题,所以假设精力同意,也应该对常见的操作符进行一定程度的研究。当发现某个低效查询中出现这个操作符时,最好还是想想其原因,并尝试能否进行优化。优化的原则则是依据其含义而定,既然这个操作符是依据现有值计算新值,那么我们的核心方案应该是降低这样的操作的数据量或者预先计算新值。总的而言。详细情况详细分析。
下一篇将介绍一个更为常见而且通常意味着有优化空间的操作符:键查找: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 执行计划操作符详解(3)——计算标量(Compute Scalar)

    接上文:SQL Server 执行计划操作符详解(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介绍第 ...

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

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

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

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

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

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

  7. SQL Server 执行计划缓存

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

  8. 微软官方提供的用于监控MS SQL Server运行状况的工具及SQL语句

    Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...

  9. Chapter 1 Securing Your Server and Network(1):选择SQL Server运行账号

    原文:Chapter 1 Securing Your Server and Network(1):选择SQL Server运行账号 原文出处:http://blog.csdn.net/dba_huan ...

随机推荐

  1. keil5下载程序时出现“internal command error”解决方法

    今天下载的时候,插入下载器,查看Debug可用看到“internal command error”,一直找不到原因,后来查看上一个工程才发现,上一个程序禁用了Seral Wire 引脚,导致的. 解决 ...

  2. STM32 GPIO重映射(转)

    重映射就是将引脚功能重新定义到其他引脚, 例如PA9是USART1-TX默认的 管脚,但是现在PA9用做它用了,那可以将USART1-TX重新映射到PB6,当然这 种映射不是随意的想映射到哪个脚就哪个 ...

  3. fetch 如何请求数据

    fetch 如何请求数据 在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好 二 与 ...

  4. Vue 做项目经验

    Vue 做项目经验 首先需要知道最基本的东西是: Vue 项目打包:npm run build Vue生成在网页上看的端口:npm run dev 修改端口号的地方在: config文件夹下index ...

  5. WinServer-IIS-身份验证\SSL设置

    匿名身份验证:不需任何加密,用的最广泛 基本身份验证:需用户名和密码,采用BASE-64加密,结合SSL证书才比较安全,加密方式很弱 windows身份验证:内网用,结合域控使用 摘要式身份验证:结合 ...

  6. 数据库联表统计查询 Group by & INNER JOIN

    原数据表 视频信息表  tab_video_info 播放记录表  tab_play_record 需求 统计播放量(已经开始播放)最多的前20个视频: SELECT a.video_id, SUM( ...

  7. 在 RedHat/CentOS 7.x 中使用 nmcli 命令管理网络

    在 RedHat/CentOS 7.x 中使用 nmcli 命令管理网络 学习了:https://linux.cn/article-5410-1.html#3_3613 http://www.linu ...

  8. PC端 java 开发蓝牙所遇到的问题

    由于项目的原因.要在电脑上开发一个通过蓝牙传送数据的client.我採用的是JAVA,JSME开发. client:去搜素蓝牙信号,然后找到对应的蓝牙信号进行连接. 服务端:client须要进行连接的 ...

  9. pcap网络抓包 无法import pcap

    坑爹的不知道从哪里看到说仅仅有pcap最多仅仅支持到python2.5,然后又是easy install又是安装pip就是无法成功import pcap... 我的python版本号是2.7.8. s ...

  10. jms及active(jdk api)的实现

    在企业中,分布式的消息队列需要实现的问题: 1.不同的业务系统分别处理同一个消息(订阅发布),同一个业务系统负载处理同一类消息(队列模式) 2.消息的一致性问题,在互联网公司中一般不要求强一致性,一般 ...