文章来自:博客园-DotNet菜园

最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做。
示例:
有表內容﹕
名称  內容
1     abc
1      aaa
1      dddd
2      1223
2       fkdjfd
--------------------------------
结果﹕
1   abc,aaa,dddd
2   1223,fkdjfd
要求用一条SQL语句实现﹐如﹕select sum(內容) from table group by 名称

--该问题,一共使用了三种方法,并分别测试了一下这三种方法的各自的性能
1: 创建处理函数
2 :  sql 2005及以上版本中的新的解决方法,FOR XML
3 :  使用临时表实现字符串合并处理的示例

说明:以下测试是以本人机器的硬件配置为准,根据硬件配置的不同,结果可能不同。

1: 创建处理函数
       说明:sql 全系列版本

CREATE FUNCTION dbo.f_strHeBin(@id int)
RETURNS varchar(8000)
AS
BEGIN
    DECLARE @r varchar(8000)
    SET @r = ''
    SELECT @r = @r + ',' + value
    FROM tb
    WHERE id=@id
    RETURN STUFF(@r, 1, 1, '')
END
GO
-- 调用函数

SELECt id, values=dbo.f_strHeBin(id)
FROM tb
GROUP BY id

以上方式得到的是根据ID合并的所有记录,如果要得到相应的单一ID的记录,则还需要添加一条语句:
假设:以上结果入到临时表3t3中:
SELECT id,max(values) as values FROM #t3 GROUP BY id

go

分析结果如下:
SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 7 毫秒。
1--使用sql 全系列版本,自定义合并函数方式

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
表 'Worktable'。扫描计数 1,逻辑读取 4030 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb'。扫描计数 2,逻辑读取 46 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 1397254 毫秒,占用时间 = 1463680 毫秒。

(1969 行受影响)

(218 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '#t3___000067'。扫描计数 1,逻辑读取 16 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 84 毫秒。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 2 毫秒。

总计耗时计:24.4分钟,这才1969行记录,这个方法看来在这种情况下不可取。

2 :  sql 2005及以上版本中的新的解决方法,FOR XML

select id,stuff(
(select '-' + convert(varchar(4),value)
from tb
where id=A.id
order by id
for xml path('')
),1,1,'') as values 
from tb A
group by   id

go

分析结果如下:

SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
表 'Worktable'。扫描计数 439,逻辑读取 32978 次,物理读取 0 次,预读 0 次,lob 逻辑读取 319 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb'。扫描计数 4,逻辑读取 92 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 1856 毫秒,占用时间 = 1955 毫秒。

总计耗时:2秒钟。不过这个方法随着记录数量的增加,性能也随之降低,在数据记录达到20000条的时候,耗时将近2.5分钟。

3 :  使用临时表实现字符串合并处理的示例

SELECT id ,values=CAST(value as varchar(8000))
INTO #t2 FROM tb
ORDER BY id

DECLARE @col1 varchar(5),@col2 varchar(8000)
UPDATE #t2 SET
    @col2=CASE WHEN @col1=id THEN @col2+'-'+values ELSE values END,
    @col1=zo3,
    qs=@col2

SELECT id,max(values) values FROM #t2 group by id

drop table #t2

go

分析结果如下:

SQL Server 分析和编译时间: 
   CPU 时间 = 7 毫秒,占用时间 = 7 毫秒。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb'。扫描计数 2,逻辑读取 46 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 734 毫秒,占用时间 = 769 毫秒。

(2012 行受影响)
表 '#t2___________000000000065'。扫描计数 1,逻辑读取 1677 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 62 毫秒,占用时间 = 62 毫秒。

(2012 行受影响)
表 '#t2__________000000000065'。扫描计数 1,逻辑读取 849 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

SQL Server 执行时间:
   CPU 时间 = 16 毫秒,占用时间 = 7 毫秒。

(218 行受影响)

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

总计耗时:769ms+62ms+15ms=846ms,总费时1秒钟不到,当数据记录达到20000条记录时,性能损耗也不太严重,在6-10秒左右。能够接受。

Sql Server中三种字符串合并方法的性能比较的更多相关文章

  1. 在SQL SERVER中批量替换字符串的方法

    UPDATE MainData SET Content = )) , 'XM00000137' , 'XM00000078') WHERE [Key] IN (SELECT md_key FROM i ...

  2. JS中三种字符串连接方式及其性能比较

    工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法  用连接符“+”把要连接的字符串连起来 ...

  3. JavaScript中三种字符串连接方式及其性能比较

    参考地址: https://www.cnblogs.com/programs/p/5554742.html 工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方 ...

  4. SQL Server中解决死锁的新方法介绍

    SQL Server中解决死锁的新方法介绍 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的 ...

  5. 在SQL Server中使用CLR调用.NET方法

    介绍    我们一起来做个示例,在.NET中新建一个类,并在这个类里新建一个方法,然后在SQL Server中调用这个方法.按照微软所述,通过宿主 Microsoft .NET Framework 2 ...

  6. 不同版本的SQL Server之间数据导出导入的方法及性能比较

    原文:不同版本的SQL Server之间数据导出导入的方法及性能比较 工作中有段时间常常涉及到不同版本的数据库间导出导入数据的问题,索性整理一下,并简单比较下性能,有所遗漏的方法也欢迎讨论.补充. 0 ...

  7. 实现SQL Server中的切割字符串SplitString函数,返回Table

    有时我们要用到批量操作时都会对字符串进行拆分,可是SQL Server中却没有自带Split函数,所以要自己来实现了. -- ===================================== ...

  8. 实现SQL Server中的切割字符串SplitString函数

    有时我们要用到批量操作时都会对字符串进行拆分,可是SQL Server中却没有自带Split函数,所以要自己来实现了.没什么好说的,需要的朋友直接拿去用吧 SET ANSI_NULLS ON GO S ...

  9. SQL Server中提前找到隐式转换提升性能的办法

        http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...

随机推荐

  1. SQL拼接方法

    smark Beetle可靠.高性能的.Net Socket Tcp通讯组件 另类SQL拼接方法 在编写SQL的时候经常需要对SQL进行拼接,拼接的方式就是直接String+处理,但这种情况有个不好的 ...

  2. VB的写法,关于版本写入注册表

    VB的写法,关于版本写入注册表   '软件都有一个关于我们的菜单,单单实现这个功能并不难,困难的是能够将这些信息写入注册表中,这样每次只要弹出这样的窗口,就从注册表里去搜索.这样是不是极大的节省了资源 ...

  3. Servlet入门和ServletConfig、ServletContext

    Servlet是一门用于开发动态web资源的技术. 若想开发一个动态web资源,需要完成以下2个步骤: 1)编写一个Java类,实现servlet接口: 2)把开发好的Java类部署到web服务器中. ...

  4. php5.3.*编译出现make: *** [ext/gd/libgd/gd_compat.lo] Error 1 解决方法

     升级系统,把php5.2.9升级到5.3.6,按照以前的编译参数,configure能正常通过,但是在make的时候提示: In file included from /root/php-5.3.6 ...

  5. jquery.range.js左右滑动选取数值插件,动态改变进度。

    作为一个初级前端工作人员,我最近在做一个关于直播的项目,其中一个功能要求是设置延迟时间, 所以就用到了jquery.range.js这个插件.插件中设置$(".single-slider&q ...

  6. poj1463 Strategic game (树状dp)

    Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 5498   Accepted: 2484 De ...

  7. poj 2378 树型dp

    和poj1655那道求树的重心基本上一样的,代码也没多大改动. 详情请见 #include<cstdio> #include<algorithm> #include<cs ...

  8. Web基础知识和技术

    WEB是一个外延广泛的概念,不单单指网站,乌徒帮专注拥有WEB界面的网站开发,帮助初学者或已经进入开发的朋友们提供参考讨论平台,然而并不一定能将所有的WEB知识讲全讲透,只是能满足初涉者的建站需求,能 ...

  9. erlang集成开发环境搭配配置出现的问题

    问题:Unable to create the selected preference page.  com.avaya.exvantage.ui.interfaces.eclipse.plugin  ...

  10. OC之OC与C的比较

    1. 从编写.编译.链接的流程. 1). 创建1个.m的源文件. 2). 在这个文件中写上符合OC语法规范的源代码. 3). 编译. a. 预编译: 执行预处理代码. b. 检查语法. c. 生成目标 ...