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

时间:2011-05-27 07:58:15

标签: .net sql-server performance linq-to-sql ado.net

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

对我来说这看起来并不明显 - 也许LinqToSql由于缓冲(+可读性)而更好,可能因为它的开销而很糟糕。

更新1:

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

更新2:

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

更新3:

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

5 个答案:

答案 0 :(得分:2)

每当你进行大量的顺序数据访问时,一些明显的问题(与LINQ-to-SQL和原始ADO.NET无关)是:

  • 你可以提取清单而不是获取
  • 你能在数据库中完成整个事情

LINQ-to-SQL增加了很多便利和静态检查,通常的开销很小;但是,如果将大量(数千)记录加载到单个数据上下文中,则身份管理器还有更多工作要做,这可能会略微影响性能。我们有时也会注意到LINQ-to-SQL加载时间中无法解释的暂停(即TSQL需要1ms,对象将需要80ms才能实现) - 这是零星的并且难以重现,但是对于批量工作,我们最终写了{{3作为替代品,允许以LINQ-to-SQL方式实现方便的实现,没有这种开销 - 但也没有能力改变它并推动更改; p当然,你可以尝试{{1}等等。

答案 1 :(得分:2)

Sam Saffron创建了一个名为dapper的微型ORM。 The project web site有一些你可能有兴趣看的基准。他们将原始DataReader与各种ORM实现进行比较,包括 LinqToSql

答案 2 :(得分:1)

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

警告 - 您在问题中写下

  

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

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

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

  

访问它但执行了数千次顺序获取/插入/更新。

如果您正在进行此操作,则应使用ADO.Net。

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

顺序获取

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

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

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

Sequential CompiledQuery

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)

1选项

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

Compiled Ranged获取

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)

1选项

--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个数据库往返。下行 - 表可能太大而无法保留在内存中,或者查询可能会超时。

from c in myDC.Customer select c;

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