SQL Server 中VARCHAR(MAX)变量赋值引起的性能问题。
案例环境:
操作系统版本 : Windows Server 2008 R2 Standard SP1
数据库版本 : Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
案例介绍:
由于不能将生产环境的代码和数据贴上来,所以我构造了下面一个小案例,当然没法和生产环境的案例一致。只能是接近而已。但是足以反映问题本质就足够了。
DROP TABLE ProductPrice;
GO
CREATE TABLE ProductPrice
(
ProductName VARCHAR(14),
Sequence INT ,
ProductPrice FLOAT
)
GO
构造8000条测试数据,然后将数据插入临时表#tmp(其实完全可以不用临时表,只因为生产环境也是临时表,故模拟接近案例环境)
DECLARE @index INT =1;
DECLARE @subindex INT;
WHILE @index <= 800
BEGIN
SET @subindex = 1;
WHILE @subindex <=10
BEGIN
INSERT INTO ProductPrice
SELECT 'product' + convert(varchar,@index), @subindex, rand()*1000;
SET @subindex = @subindex +1;
END;
SET @index = @index +1;
END
SELECT * INTO #tmp FROM ProductPrice;
GO
本来开发人人员也许是要使用动态SQL语句获取下面这样一段SQL语句(随意构造小例子,形似神不似)
DECLARE @sqlText NVARCHAR(MAX) ='';
SELECT @sqlText=@sqlText+ quotename(productname)+
'=CAST(MAX(CASE WHEN [productname]='+QUOTENAME(productname,'''')
+' THEN [productPrice] END) AS VARCHAR)'
FROM #tmp
GROUP BY ProductName
SELECT datalength(@sqlText);
但是由于疏忽或是对动态SQL不了解,写成了这样一个SQL语句,结果执行时间一下子飚增到7分多钟。
DECLARE @sqlText NVARCHAR(MAX) ='';
SELECT @sqlText=@sqlText+ quotename(productname)+
'=CAST(MAX(CASE WHEN [productname]='+QUOTENAME(productname,'''')
+' THEN [productPrice] END) AS VARCHAR)'
FROM #tmp ;
SELECT datalength(@sqlText);
看来SQL对于处理非常长的字符串对象有一定的性能问题,于是为了验证我的想法,我又构造了下面一个例子。创建临时表#tmp,数据来源于 sys.all_columns
DROP TABLE #tmp;
GO
SELECT * INTO #tmp FROM sys.all_columns;
GO
7364 行受影响)
然后我们来看一下下面SQL语句
DECLARE @output NVARCHAR(MAX)
SELECT @output=ISNULL(@output,'') + QUOTENAME(name) + REPLICATE('it is only a test ', 200)
FROM #tmp
那么我们来看看这条SQL的执行计划,如下所示,很普通的执行计划,看不出有啥特别之处。但是执行性能那叫一个糟糕透顶!
SET SHOWPLAN_ALL ON;
GO
DECLARE @output NVARCHAR(MAX)
SELECT @output=ISNULL(@output,'') + QUOTENAME(name) + REPLICATE('it is only a test ', 200)
FROM #tmp
StmtText的内容,如下所示:
DECLARE @output NVARCHAR(MAX)
SELECT @output=ISNULL(@output,'') + QUOTENAME(name) + REPLICATE('it is only a test ', 200)
FROM #tmp
|--Compute Scalar(DEFINE:([Expr1004]=isnull([@output],CONVERT_IMPLICIT(nvarchar(max),'',0))+quotename([tempdb].[dbo].[#tmp].[name])+N'it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is only a test it is onl'))
|--Table Scan(OBJECT:([tempdb].[dbo].[#tmp]))
虽然能理解处理大对象需要很多资源,会产生一定的性能问题,但是执行时间这么长,还是让我觉得有点不可思议,但是又不清楚具体原因!
SQL Server 中VARCHAR(MAX)变量赋值引起的性能问题。的更多相关文章
- SQL Server中VARCHAR(MAX)和NVARCHAR(MAX)使用时要注意的问题(转载)
在Microsoft SQLServer2005及以上的版本中,对于varchar(n).nvarchar(n)和varbinary(n)有了max的扩展.可以使用如:varchar(max).nva ...
- SQL SERVER中LIKE使用变量类型输出结果不同
前言:Sql Server中LIKE里面使用不同的变量类型导致查询结果不一致的问题,其实看似有点让人不解的现象背后实质跟数据类型的实现有关. 一.我们先来创建示例演示具体操作 CREATE TABLE ...
- SQL Server中 SET 和 SELECT 赋值有什么区别?
SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT.对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们并没有注意,其实这两种 ...
- SQL SERVER中SELECT和SET赋值相同点与不同点
SELECT和SET在SQL SERVER中都可以用来对变量进行赋值,但其用法和效果在一些细节上有些不同. 1. 在对变量赋值方面,SET是ANSI标准的赋值方式,SELECT则不是.这也是SET方式 ...
- SQL Server中提前找到隐式转换提升性能的办法
http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...
- SQL SERVER中LIKE使用变量类型不同输出结果不一致解惑
一同事在写脚本时,遇到一个关于LIKE里面使用不同的变量类型导致查询结果不一致的问题,因为这个问题被不同的人问过好几次,索性总结一下,免得每次都要解释一遍,直接丢一篇博客岂不是更方便!其实看似有点让人 ...
- SQL Server中,varchar和nvarchar如何选择
正常情况下,我们使用varchar也可以存储中文字符,但是如果遇到操作系统是英文操作系统并且对中文字体的支持不全面时, 在SQL Server存储中文字符为varchar就会出现乱码(显示为??). ...
- Sql Server中三种字符串合并方法的性能比较
文章来自:博客园-DotNet菜园 最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做.示例:有表內容﹕名称 內容1 abc1 ...
- SQL Server中varchar和nvarchar的区别
varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节.nvar ...
随机推荐
- Zookeeper数据模型及其应用
Zookeeper作为分布式系统的底层协调服务有着其简单可依靠的数据模型,数据模型加之数据同步.一致性处理和可靠性,在此之上有很多经典的应用,例如,分布式锁.服务器动态上线下感知.主节点选举.数据发布 ...
- 【JUC】JDK1.8源码分析之AbstractQueuedSynchronizer(二)
一.前言 在锁框架中,AbstractQueuedSynchronizer抽象类可以毫不夸张的说,占据着核心地位,它提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.所以很有必 ...
- js构建ui的统一异常处理方案(一)
从早期从事基于java的服务器端开发,再到之后从事基于web和js的ui开发,总体感觉基于web页面的ui开发远不如服务器端健壮.主要是早期ie浏览器功能太弱小,很多业务被迫放到服务器端去实现,浏览器 ...
- Git-TortoiseGit完整配置流程
每次使用Git的时候都或多或少遇到些问题,为了方便以后少踩一些坑,把自己踩过的坑记录一下,加深对Git使用的理解,所以写下这篇日记记录一下. 本文需要频繁使用cmd,如果使用系统的cmd会稍微有点不便 ...
- 六、CsrfViewMiddleware
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF. 你这可 ...
- 自己封装的一个LoadRes组件
这两周一直太忙,没有好好处理上上上周遇到的一个让我加班到凌晨的问题,这个问题是判断flash的加载. 之前的思路是让flash的人在制作flash的时候,加入了一个回调方法,该方法再会回调我页面的方法 ...
- 【转】单例模式(Singleton)
首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了, 比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个, 这里就可以通过单例模式来避免两个打印作业同时输 ...
- es6 中增强的对象字面量
http://www.cnblogs.com/Wayou/p/es6_new_features.html 对象字面量被增强了,写法更加简洁与灵活,同时在定义对象的时候能够做的事情更多了.具体表现在: ...
- Ehcache 缓存使用
在开发高并发量,高性能的网站应用系统时,缓存Cache起到了非常重要的作用.本文主要介绍EHCache的使用,以及使用EHCache的实践经验. 笔者使用过多种基于Java的开源Cache组件,其中包 ...
- 转载:《TypeScript 中文入门教程》 13、类型兼容性
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 TypeScript里的类型兼容性基于结构子类型的. 结构类型是只一种只使用其成 ...