微软linq技术已经出现很久,很多公司已经开始商业使用,作为我们暂时没有用到的人来说,也应该适当的了解下相关知识,但是直到目前网络上对他的看法仍然是褒贬不一,当然任何事情都不可能完美的,下面就针对大多数人比较关注的效率问题做一次试验,来实实在在的用事实说次话,(由于过年在家无事突发奇想做的试验也没用到专业测试工具,但就大体而言,能说明问题就够了)
声明:本测试全部原创,属于个人爱好测试,如转载,希望保留作者,另外,如不认同或专业使用可另行测试
测试目的:主要是测试两者的时间区别
测试者:石曼迪(shiyeping@163.com)
测试环境:
CPU:奔腾双核T3400(2.16G) 内存:2G 667 硬盘:160G 操作系统:XP SP3 编译工具:vs 2008+mssql 2005 |
测试依据(非专业精密工具):
Stopwatch 类 提供一组方法和属性,可用于准确地测量运行时间。 Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间。在典型的 Stopwatch 方案中,先调用 Start 方法,然后调用 Stop 方法,最后使用 Elapsed 属性检查运行时间。 Stopwatch 实例或者在运行,或者已停止;使用 IsRunning 可以确定 Stopwatch 的当前状态。使用 Start 可以开始测量运行时间;使用 Stop 可以停止测量运行时间。通过属性 Elapsed、ElapsedMilliseconds 或 ElapsedTicks 查询运行时间值。当实例正在运行或已停止时,可以查询运行时间属性。运行时间属性在 Stopwatch运行期间稳固递增;在该实例停止时保持不变。 默认情况下,Stopwatch 实例的运行时间值相当于所有测量的时间间隔的总和。每次调用 Start 时开始累计运行时间计数;每次调用 Stop 时结束当前时间间隔测量,并冻结累计运行时间值。使用 Reset 方法可以清除现有 Stopwatch 实例中的累计运行时间。 Stopwatch 在基础计时器机制中对计时器的刻度进行计数,从而测量运行时间。如果安装的硬件和操作系统支持高分辨率性能的计数器,则 Stopwatch 类将使用该计数器来测量运行时间;否则,Stopwatch 类将使用系统计数器来测量运行时间。使用 Frequency 和 IsHighResolution 字段可以确定实现 Stopwatch 计时的精度和分辨率。 Stopwatch 类为托管代码内与计时有关的性能计数器的操作提供帮助。具体说来,Frequency 字段和 GetTimestamp 方法可以用于替换非托管 Win32 APIQueryPerformanceFrequency 和 QueryPerformanceCounter。
|
测试前准备:
新建一个数据库:SpeedTest,插入500万条记录用时38分57秒,最终数据库大小:213M
见表语句如:
CREATE TABLE Tab( Id int IDENTITY(1,1) NOT NULL, Context nvarchar(50) NOT NULL, DoTime datetime NOT NULL ) |
测试代码见附件
插入语句如:
declare @i int,@start datetime,@end datetime set @i=0 set @start=getdate() while(@i<5000000) begin insert into tab(context,dotime)values('值:'+convert(varchar(20),rand()*10*rand()),getdate()) set @i=@i+1 end set @end=getdate() print '插入500万条数据用时:'+convert(varchar(20),datediff(ms,@start,@end)) |
第一轮测试——查询
查询第100000到120000条数据中的长度为8的数据
查询用SQL语句如:
--查询第到条数据中的长度为的数据 declare @start datetime,@end datetime set @start=getdate() select * from ( select top 20000 * from tab where id not in(select top 100000 id from tab)) as t where len(t.Context)=8 set @end=getdate() print '插入万条数据用时:'+convert(varchar(20),datediff(ms,@start,@end)) |
测试结果如:
单位:秒
第一次 | 第二次 | 第三次 | 第四次 | 第五次 | 第六次 | 第七次 | 第八次 | 第九次 | 第十次 | |
Linq | 0.6788 | 0.681 | 0.6704 | 0.6804 | 0.686 | 0.6555 | 0.6753 | 0.677 | 0.6717 | 0.6744 |
SQL | 0.5653 | 0.5498 | 0.5699 | 0.5673 | 0.5699 | 0.5795 | 0.5756 | 0.5869 | 0.5749 | 0.5735 |
MSSQL | 0.156 | 0.110 | 0.143 | 0.170 | 0.126 | 0.156 | 0.126 | 0.143 | 0.140 | 0.126 |
第二轮测试——修改
查询用SQL语句(把能被5整除的数据修改为“测”,应该影响1000000行):
update tab set Context=Context where id%5=0 |
测试结果如下:
本来想批量修改数据的,更新100万行使用SQL语句用时基本在5.4——5.8秒之间,但是使用LINQ基本就挂了,5分钟都出不了结果,看来如果是批量修改,特别是大批量修改,还是尽量避免使用LINQ
现在就改变下测试思路,修改其中一条数据。
update tab set DoTime=dateadd(ms,1,DoTime) where id=2500000 |
测试结果如下:
第一次 | 第二次 | 第三次 | 第四次 | 第五次 | 第六次 | 第七次 | 第八次 | 第九次 | 第十次 | |
Linq | 0.2068 | 0.2022 | 0.2029 | 0.2064 | 0.2055 | 0.2025 | 0.2067 | 0.2012 | 0.2058 | 0.2031 |
Sql | 0.1466 | 0.1425 | 0.1386 | 0.1419 | 0.1457 | 0.1388 | 0.142 | 0.1384 | 0.1388 | 0.1426 |
第三轮测试——插入
批量插入1万条数据
测试结果如下:
单位:秒
第一次 | 第二次 | 第三次 | 第四次 | 第五次 | 第六次 | 第七次 | 第八次 | 第九次 | 第十次 | |
Linq | 9.4243 | 9.5757 | 9.2637 | 9.5913 | 9.5264 | 9.573 | 9.5606 | 9.5448 | 9.4261 | 9.7743 |
Sql | 8.7681 | 8.4239 | 7.9236 | 7.8332 | 7.8264 | 8.0614 | 7.997 | 7.979 | 7.888 | 8.2885 |
综上所述,LINQ这个新技术,在代码上和思想上的确很有优势,但是归根结底还是使用的是.net 2.0 的框架,只是抽象了一个接口而已,生成SQL语句的过程被LINQ完成,所以说LINQ即使到了极限也不能超越传统的SQL,另外据查资料,LINQ另一个瓶颈在于Lambda表达式。我们可以得出在效率要求不高的应用型系统中,使用LINQ还是很有优势的,毕竟代码少,维护方便,但是在修改操作上,特别是批量修改就毫无优势可言,效率低是一方面,内存在占用也是一个大问题,所以现在很多公司的做法就是两者混合起来用,不失为一个明智的选择。
试验用代码和文档:下载