简单测试linq to sql性能

前些日子,做了一个物业收费系统,cs模式,用到了linq to sql 技术,这是我第一次使用这个东东写程序存取数据库,迷迷糊糊搞得一塌糊涂,当时有个同学他们找好的分页组件,然后写好了调用方法,由于时间比较急,而且第一次用,所以没有怎么研究就直接按照注释使用他们写好的分页方法,然而开发过程中一直都对他们写的方法有怀疑,会不会是一种投机取巧,胡编乱造的?后来我也做过一些简单分析,我发现程序在业务逻辑层中每次都从数据库中将数据全部读取出来,然后循环将数据转成特定的List,也就是遍历整个数据集合,然后在显示层中将List进行分页,最后放到DataGridView中,其中列名自动设定为类的属性值,刚开始我还一直认为这样的方法好方便啊,一下子全部生成了,直到程序马上接近尾声时,我发现程序的操作日志记录已经达到了4500条,每次打开日志管理界面时,程序都要加载上半天才能出来,我彻底对linq产生了怀疑,确切的说并不是对linq产生怀疑,而是分页方法以及程序算法产生了怀疑。
    显示层的分页代码部分:dataGridView.DataSource = data.Take(pagerControl1.PageSize * pagerControl1.PageIndex).Skip(pagerControl1.PageSize * (pagerControl1.PageIndex - 1)).ToList();,其中data是业务逻辑层获取到的数据,业务逻辑层:

var data = from d in jx.LogTable

orderby d.OperTime descending

where Tflag.Equals("全部") ||

((d.OperTime >= t1 && d.OperTime <= t2) && (d.OperName.Contains(content) || d.UserID.Contains(content)))

select d;

List<LogTable> items = new List<LogTable>();

foreach (var d in data)

{

LogTable item = new LogTable();

item.编号 = trim(d.ID);

item.事件 = trim(d.OperName);

item.操作员 = trim(d.UserID);

item.标志 = trim(d.mark);

item.操作时间 = trim(d.OperTime);

items.Add(item);

}

return items;

此处不仅将所有数据全部读取出来了,而且还遍历了一遍,当数据达到4500条时就出现了卡顿现象,情况糟糕程度可想而知,好丑陋的代码啊,而且程序牵扯到这个的地方简直多的要命,如果要改动的话,一定是一场灾难!
    之前一直在忙,没有时间去测试程序中所存在的问题以及如何能更高效的使用linq开发应用程序,今天挤出点时间来做了个小小的测试,这让我重新对linq产生了兴趣。
    测试中的数据库表仍然不改变,还是操作日志表,不同的是我在该表中追加了更多的数据,总记录数几乎达到 110万条,然后对这110万条数据进行测试。具体测试如下:
    当点击数据总条数时,弹出数据库操作日志表的总记录数,点击加载数据时,对110万条数据进行分页 , 每页10条,取第三页的10条数据,点清空数据时,对表格中加载的数据进行清空处理:

总条数如下:

首次运行,点击加载数据时,共耗时9100毫秒:

然后点击清空数据,再次点击加载数据时,共耗时2899毫秒:

之后重复测试,时间一直保持在3000毫秒左右,也就是3秒钟,第二次点击后发现时间明显加快了,3倍有余,但是我想说的是这个速度还是非常非常慢的,因为表中的数据列所存储的值很小,没有什么大的数据,为什么会这么慢呢?看代码:

Stopwatch sw = new Stopwatch();

sw.Start(); //开始计时

var data = (from d in db.Log select d).ToList();//将数据全部查询出来,并且ToList()

dataGridView1.DataSource = data.Skip(20).Take(10).ToList();//分页

sw.Stop();   //计时结束

MessageBox.Show("共耗时:"+sw.ElapsedMilliseconds.ToString()+"毫秒"); 
 然后我对代码做了改变,如下:
            Stopwatch sw = new Stopwatch();

sw.Start(); //开始计时

var data = (from d in db.Log select d);//只是写好了查询条件,注意此处

dataGridView1.DataSource = data.Skip(20).Take(10).ToList();//分页

sw.Stop();   //计时结束

MessageBox.Show("共耗时:"+sw.ElapsedMilliseconds.ToString()+"毫秒"); 
其实只是将上边标红的地方删掉了,也就是ToList()部分, 采用控制变量法,其他数据和条件全部不做任何变动,看效果:
首次点击加载数据时,共耗时185毫秒:

清空后,第二次点击加载数据时,共耗时39毫秒:

之后测试,一直保持在40毫秒左右,差距为什么会这么大?

其实,LINQ执行过程的一个重要特征是延迟加载,就是知道要获取数据时,才会进行计算。大家可能认为执行完var data = from db.Log select d语句,然后在开始skip,take函数进行分页,所有的值都会存到data中了,实际上,这条语句会延迟到foreach或者ToList()调用时才会执行。而var data = (from db.Log select d)Skip(20).Take(10);语句执行完之后,程序只是生成了一个比较完美的sql语句等待着执行,直到ToList()或者foreach出现,也就是一直等待程序需要获取数据时才开始执行数据库查询,这就解释了为什么差距会这么大的问题,同时也说明了linq进行分页的效率还是非常可以的,在110万条记录下进行分页最多需要大约200毫秒时间,最快大约40毫秒。
    一定要注意:先分页在获取,而不是先获取再分页!

于是,为了测试效率,我将数据追加到了220万条,重新测试:

发现首次查询时,共耗时195毫秒:

清空后,再次查询,共耗时 37毫秒:

大功告成,经过测试,在linq分页前不能调用读取方法,应该分页后再查询...看来本次的项目开发可以大胆的继续使用linq来操作数据库了。当然,之前的物业管理系统,等忙完这一段时间,我得帮忙改改去,做人得负责任啊!!!

  没文化真可怕,这么简单的问题竟然现在才知道!

时间: 2024-08-03 19:23:36

简单测试linq to sql性能的相关文章

构建一个简单的 linq to sql

先看下运行结果: public class Customer<T> : IQueryable<T>, IOrderedQueryable<T> { public Customer(Expression ex, IQueryProvider Provider) { this.ElementType = typeof(T); this.Expression = ex; this.Provider = Provider; } public Customer() : this(

LINQ To SQL 的性能 (列出部分的测试程序)

摘要:LINQ To SQL 的性能 (列出部分的测试程序) 一时兴起,测了一下LINQ To SQL的性能, ?以100000笔数据的读入来测试,为求平衡,特别以5次读取之总值测试. 读取方式 结果 With Un-Typed DataTable Load (use DataAdapter without Delete/Insert/Update assocation) 5188 ms With LINQ To SQL??????????????????????????????????????

Windows IO 性能简单测试

转自:http://bbs.csdn.net/topics/360111289, 有改动. #include <windows.h>#include <stdio.h>#include <process.h>#include<memory>#pragma comment(lib,"ws2_32.lib")ULONGLONG g_nReadCounts=0,g_nWriteCounts=0,g_nOtherCounts=0,g_nReads

Linq to SQL 简单增删改查

Linq to SQL 简单增删改查 用Linq大大减少了对数据库的一般操作所需的编码量. 运行下面事例之前,首先建一个叫做Alien的数据库表. CREATE TABLE [dbo].[Aliens](    [Id] [int] IDENTITY(1,1) NOT NULL primary key,    [Name] [nchar](10) NULL,) 建一个console项目,在项目里添加一个Linq To Sql类文件(.dbml以及两个附属文件),把Alien表从服务器资源管理器拖

ab工具使用(测试平台的并发性能)简单介绍一下

Apache -- ab工具主要测试网站的(并发性能) 这个工具非常的强大. 基本语法 :   cmd>ab.exe –n 请求总次数  -c 并发数 请求页面的url    进入到ab.exe目录 举例:  cmd>ab.exe –n 10000 –c 100 http://localhost/test.php 简单test结果简单介绍一下: ab工具使用(测试平台的并发性能)简单介绍一下

linq to sql简单使用

1.新建一个winform项目. 2.添加一个Linq to Sql 类,命名为Northwind 3.打开服务器资源管理器,将表拖动到linq to sql 类,实体类就由Vs生成了 4.实例化DataContext类 class="brush:csharp;gutter:true;">NorthwindDataContext dc = new NorthwindDataContext(); 5.下面就可以使用Linq to Sql啦. a.查询Employees所有数据 va

Java学习-排序二叉树性能简单测试

1.创建4万个随机数,然后用分别用冒泡法,选择法,二叉树法3种排序算法进行排序,比较哪种更快 1 package Collection; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class sortSpeedTest { 7 8 public static void main(String[] args) { 9 int num = 40000; // 元素个数 10 int rnd1[] = new

LINQ之路10:LINQ to SQL 和 Entity Framework(下)

在本篇中,我们将接着上一篇“LINQ to SQL 和 Entity Framework(上)”的内容,继续使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术的关键特性.我们在此关注的是LINQ to SQL和Entity Framework中的”LINQ”部分,并会比较这两种技术的相同和不同之处.通过我们之前介绍的LINQ知识还有将来会讨论的更多LINQ Operators,相信阅者能针对LINQ to SQL和Entity Framework写出优雅

【转载】ADO.NET与ORM的比较(3):Linq to SQL实现CRUD

[转载]ADO.NET与ORM的比较(3):Linq to SQL实现CRUD 说明:个人感觉在Java领域大型开发都离不了ORM的身影,所谓的SSH就是Spring+Struts+Hibernate,除了在学习基础知识的时候被告知可以使用JDBC操作数据库之外,大量的书籍中都是讲述使用Hibernate这个ORM工具来操作数据.在.NET中操作数据库的方式有多种,除了最直接的方式就是使用ADO.NET之外,还可以使用NHibernate这个Hibernate在.NET中的实现ORM,如果你对第