相关文章推荐
聪明伶俐的大象  ·  终于有人把 Docker ...·  1 年前    · 
痴情的篮球  ·  SwiftUI - ...·  1 年前    · 

linq to sql 是一个代码生成器和ORM工具,他自动为我们做了很多事情,这很容易让我们对他的性能产生怀疑。但是也有几个测试证明显示在做好优化的情况下,linq to sql的性能可以提升到ado.net datareader性能的93%。

因此我总结了linq to sql的10个性能提升点,来优化其查询和修改的性能。

1. 不需要时要关闭 DataContext的ObjectTrackingEnabled 属性

using (NorthwindDataContext context = NorthwindDataContext()) context.ObjectTrackingEnabled = false

关闭这个属性会使linq to sql停止对对象的标识管理和变化跟踪。但值得注意的是关闭ObjectTrackingEnabled 意味着也将DeferredLoadingEnabled属性设置为false,当访问相关表时会返回null。

2. 不要把所有的数据对象都拖到一个DataContext中

一个DataContext代表一个工作单元,并非整个数据库。如果几个数据库对象之间没有关系,或者在程序中用不到的数据库对象(例如日志表,批量操作表等等),让这些对象消耗内存空间和DataContext对象跟踪服务是完全没有必要的。

建议将所有的数据库对象按工作单元分给几个DataContext来处理。你也可以通过构造函数配置这些DataContext使用相同的数据库连接,这样也可以发挥据库连接池的用途。

3. CompiledQuery --- 有必要就得用

在创建一个linq to sql表达式并将它转换成对应的sql语句执行的过程,需要几个关键的步骤

1) 创建表达式树
2) 转换成sql
3) 运行sql语句
4) 取回数据
5) 将数据转换成对象

很显然,当我们一遍又一遍的执行相同的查询时,上面1),2)两个步骤重复执行是在浪费时间。使用System.Data.Linq命名空间下的CompiledQuery类的Compile方法可以避免这种浪费。

请看下面的使用示例:

Func<NorthwindDataContext, IEnumerable<Category>> func = CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>> ((NorthwindDataContext context) => context.Categories. Where<Category>(cat => cat.Products.Count > 5));

7. 仅在有必要时使用Attach方法。

在linq to sql中对象附加是一个的非常好用的机制,但是什么事情都不是免费的。当在DataContext中Attach对象时,就意味着过一段时间你会使用这个对象,DataContext会给这个对象做“马上要做修改的”标记。

但是有时候Attach并非必要,例如使用AttachAll去附加一个集合,这个集合中的元素并非都会发生变化。

8. 注意实体标识管理的开销

在一个非只读的DataContext中,对象一直会被跟踪,因此要知道在非直觉的情况下也可能会导致DataContext做对象跟踪,请看下面的代码

using (NorthwindDataContext context = NorthwindDataContext()) context.Categories select


这两种写法哪一种更快呢,事实证明第二个语句比第一个要快得多 http://blogs.msdn.com/ricom/archive/2007/06/29/dlinq-linq-to-sql-performance-part-3.aspx

为什么呢? 因为在第一个查询中查询出的每一个对象都需要存储在DataContext中,并对他们做可能会发生变化的跟踪,而在第二个查询中你生命了一个新的对象,就不需要再做跟踪了,所以第二个语句效率会高一些。

9. Linq to sql 提供了Take和Skip方法,使用他们来取需要的记录,不要把整个表中的记录都取下来

10. 不要滥用CompiledQuery 方法,如果你确认某个查询只会执行一遍,那就不要使用CompiledQuery来了 ,使用它也是需要付出代价的。

最后希望这些技巧对你有用。欢迎发表评论。

本文是翻译文章;

原文请看 http://www.sidarok.com/web/blog/content/2008/05/02/10-tips-to-improve-your-linq-to-sql-application-performance.html

linq to sql 是一个代码生成器和ORM工具,他自动为我们做了很多事情,这很容易让我们对他的性能产生怀疑。但是也有几个测试证明显示在做好优化的情况下,linq to sql的性能可以提升到ado.net datareader性能的93%。因此我总结了linq to sql的10个性能提升点,来优化其查询和修改的性能。1. 不需要时要关闭 DataContext的ObjectTrac Flame是C#库的集合,用于构建可读取,分析,优化和编写托管语言的工具。 您可以使用Flame构建的内容包括优化编译器,IL优化器,静态分析器等。 主要功能包括: 静态单一分配(SSA)形式的中间表示(IR)。 最先进的优化编译器(例如LLVM和GCC)偏爱这种类型的IR。 Flame IR是从头开始设计的,其明确意图是使其尽可能适用于广泛的优化和分析。 在Flame IR上运行的大量优化过程。 这些过程包括积极的优化,例如内联,聚合的部分标量替换,全局值编号, LINQ 优化,尾部调用优化。 各种IR分析。 这些分析提取未在Flame IR中明确编码的信息。 例如,有些分析可以计算支配树,值编号,块前身信息,值可为空。 可插拔的体系结构。 Flame方便地包含许多内置的转换和分析,但是有时这些通用算法不能完全覆盖您的用例。 在这种情况下,您可以轻松实现自己的转换或分析。 CIL前端和后端。 Flame可以将CIL转换为Flame IR,反之亦然,使您可以在Flame IR提供的以优化和分析为重点的抽象层进行操作时轻松读取和/或写入CIL。 有关Flame主要概念的介
1/1/2021 更新 我正在从这个项目继续前进,并为其他项目做出贡献。 请参阅了解实现相同目标的优秀库及其相对性能。 在各种实现中存在权衡,通过将您的场景与跨库的基准进行比较,您可以针对您的场景进行优化。 如果您想最简单地就地“​​不要丢失我的类型信息 LINQ ,这样您就可以做一些效率低下的事情”(在.NET Standard / Core中比Framework少见)-我建议使用 。 如果你想要最好的性能并且愿意修改你的代码来获得它,我认为可能是最适合你的。 该库通过避免信息丢失在 LINQ 之上进行优化。 LINQ 的许多方法可以更好地针对 ICollection 或 IList 实现,而且确实在许多情况下, LINQ 本身会进行这些优化。 不幸的是,它通常只在原始输入是 ICollection/IList 时执行它们,并且一旦您调用 LINQ 方法并返回 IEnumera
LINQ 语法非常好,但其作用是什么?我们只要查看源数组,就可以看出需要的结果,为什么要查询这种一眼就能看出结果的数据源呢?有时查询的结果不那么明显,在下面的示例中,就创建了一个非常大的数字数组,并用 LINQ 查询它。(1)与以前一样,创建项目时,Visual Studio 会自动在Program.cs 中包含 Linq 名称空间。usingSystem; usi...
linq 查询结果进行迭代时, linq 才去执行查询,就是说{在迭代时,才真正执行}.这是延迟操作的一种性能提升的表现. 但试想下,需要对结果进行第2次,第3次...,那么这种延迟执行,却是性能的一个瓶颈. 测试如下代码: public IEnumerable GetValue() List lst = new Lis
using (var context = new MyDbContext()) var query = context.Database. Sql Query<MyModel>("SELECT * FROM MyTable WHERE MyColumn = @p0", "myValue"); var results = query.ToList(); 在上面的示例中,我们使用` Sql Query`方法来执行原生 SQL 语句,并将结果映射到`MyModel`类型的对象列表中。`@p0`是一个参数占位符,它将在查询执行时被替换为`"myValue"`。可以根据需要添加更多的占位符参数。 需要注意的是,使用原生 SQL 语句可能会导致一些安全问题,因此应该谨慎使用,并确保对输入参数进行适当的验证和过滤。