微软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还是很有优势的,毕竟代码少,维护方便,但是在修改操作上,特别是批量修改就毫无优势可言,效率低是一方面,内存在占用也是一个大问题,所以现在很多公司的做法就是两者混合起来用,不失为一个明智的选择。
试验用代码和文档:下载