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

前言:

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

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

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

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

假设再检查文本化运行计划就能够看到仅仅有一个操作符:
       |--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

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

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

和文本化运行计划:
  |--Compute Scalar(DEFINE:([Expr1002]='A - B'))
|--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. GitHub上搭建私人hexo博客操作教程

    GitHub上搭建hexo博客 安装GitGit:主要用于上传博客页面到github和命令操作安装NodeNode.js:Hexo的运行环境安装HexoHexo:博客程序打开安装Git后的生成的右键菜 ...

  2. IOS系统兼容input keyup事件

    最近在做移动端模糊搜索功能,js监听input的keyup事件,在chrom模拟器和android手机环境运行都没有问题,到了ios手机却出现bug,没法实现功能: 查了好一会资料,发现keyup事件 ...

  3. Mybatis解决了JDBC编程哪些问题

    一:Mybatis简介 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创 ...

  4. CSVHelper读出乱码 解决方案

    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read)) using (StreamRe ...

  5. poj3249 Test for job 【图的DAG dp】

    #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> ...

  6. 一个ibatis映射文件的例子(包含增删改单查,多查)

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-/ ...

  7. select … into outfile 备份恢复(load data)以及mysqldump时间对比

    select … into outfile 'path' 备份 此种方式恢复速度非常快,比insert的插入速度要快的多,他跟有备份功能丰富的mysqldump不同的是,他只能备份表中的数据,并不能包 ...

  8. 在ubuntu下访问windows硬盘出现错误:Error mounting /dev/sda7 at /media

    在终端输入以下代码: sudo apt-get install ntfs-3g sudo ntfsfix /dev/sda7 运行完后: 这样就可以成功访问了.

  9. .net中MVC Webapi多参数调用控制器方法

    http://blog.csdn.net/wulex/article/details/71545471 路由 public static void Register(HttpConfiguration ...

  10. CBO基础概念

    CBO基础概念 CBO:评估 I/O,CPU,网络(DBLINK)等消耗的资源成本得出 一.cardinality cardinality:集合中包含的记录数.实际CBO评估目标SQL执行具体步骤的记 ...