与普通ADO相比,LinqToSql对性能的影响是什么.Net,用于一个非常简单的SQL Server数据库



我正在用C#开发一个数字运算应用程序。它将使用一个非常简单的表结构的数据库(尽管有很多记录),并且没有并发客户端(但可能有一个客户端的一些线程)来访问它,但要进行成千上万的顺序获取/插入/更新。我应该更好地使用纯ADO吗。Net查询还是LinqToSQL?

这对我来说并不明显——也许LinqToSql更好是因为缓冲(+可读性),也许它不好是因为它的开销。

更新1:

我这里有一个非常简单的模型——3个表,每个表大约有10个字段。没有外键(KISS原则牺牲了规范化)。我可以使用Excel表来实现这一点,但我更喜欢编码C#+SQL而不是VBA,并且相信SQL Server更快(并且允许更多记录)。

更新2:

我真的不需要任何ORM,简单的SQL查询就足够了。我之所以考虑LinqToSql,有三个原因:1。它允许可视化、图表优先的数据库生成。LINQ看起来比将查询作为字符串文字要好。3.从逻辑上讲,它可能(也可能不会)通过批量更新/插入提交、缓存读取和延迟加载来提高性能。

更新3:

我有4GB的RAM,不介意应用程序在处理数据时使用所有的gig。

任何时候你都在进行如此多的顺序数据访问,有几个明显的问题(与LINQ to SQL与原始ADO.NET无关)是:

  • 你能拉列表而不是获取吗
  • 你能在数据库里完成全部工作吗

LINQ to SQL增加了很多便利性和静态检查,通常的开销非常小;但是,如果将大量(数千)记录加载到单个数据上下文中,身份管理器将有更多的工作要做,这可能会对性能产生轻微影响。我们有时也会注意到LINQ到SQL的加载时间出现了无法解释的暂停(即TSQL需要1ms,对象需要80ms才能实现)——这是偶然的,很难复制,但对于批量工作,我们最终将dapper作为一种临时替换来写,从而以LINQ到SQL风格的方式方便地实现,没有这种开销,但也没有能力对其进行变异并推动变革;p当然,您可以尝试Attach等。

Sam Saffron创建了一个名为dapper的微ORM。项目网站上有一些你可能感兴趣的基准测试。它们将原始DataReader与各种ORM实现进行比较,包括LinqToSql

一般来说,根据你的描述,你可以很好地使用Linq-to-sql

一句警告的话-你在你的问题中写下

从逻辑上讲,它可能会(也可能不会)通过批量更新/插入提交、缓存读取和延迟加载来提高性能。

在批量更新/插入的情况下,Linq肯定不会提高您的性能。相反,使用SP的大容量更新或使用SqlBulkCopy的大容量插入比Linq-sql快一个数量级。

不要关心任何技术的开销,除非在对性能高度敏感的项目中工作或遇到可衡量的性能问题。

过早的优化是万恶之源。看看http://c2.com/cgi/wiki?PrematureOptimization

作为对评论的回应:我最初的回答主要针对问题的最后一部分,其中OP表示了对更高级别技术(LINQ查询)相对于较低级别技术(原始查询)的开销的担忧。当然,你根本不应该忽视性能。但是,当OP谈到一种相当简单的应用程序时,它应该会在性能方面产生很大的差异。在这些情况下,由于可读性、灵活性和可维护性,我总是选择更高级别的技术。

访问它,但要执行成千上万的顺序获取/插入/更新。

如果这就是你正在做的,你应该使用ADO.Net.

使用LinqToSql查询单个表的数据有五种方法。在这里,它们从最慢到最快:

顺序获取

这很慢,因为必须将表达式树转换为sql,并且每行都必须进行数据库往返

N表达式树和动态生成方法。N个数据库往返。

from c in myDC.Customers where c.Id = myId select c;

顺序编译查询

1表达式树和动态方法生成。N个数据库往返。

Func<MyDataContext, int, IEnumerable<Customer>> compiledQuery =
  (dc, i) => from c in dc.Customers where c.Id = i select c;

Ranged获取

N/PageSize表达式树和动态方法生成。N/PageSize数据库往返。

(from c in myDC.Customers where c.Id > myId order by c.Id select c).Take(pageSize)

选项2

  --note, sql server has an upper limit of ~2100 parameters.
from c in myDC.Customers where myIds.Contains(c.Id) select c;

Compiled Ranged gets

1表达式树和动态方法生成。N/PageSize数据库往返。

Func<MyDataContext, int, IEnumerable<Customer>> compiledQuery =
  (dc, i) => from c in dc.Customers where c.Id > i order by c.Id select c).Take(pageSize)

选项2

--note, .Contains method not supported by compiled query due to varying parameter count.
--instead the expression has to be built from the ground up - this is hard, but not impossible.

表转储

1表达式树和动态方法生成。1个数据库往返。Downside-表可能太大而无法容纳在内存中,或者查询可能会超时运行。

from c in myDC.Customer select c;

使用ADO.Net,您不需要执行Expression->Sql转换,并且将DataReader行转换为对象的方法是由您编写的,而不是动态生成的。默认情况下,您应该在CompiledQuery级别看到性能。

最新更新