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
语句可能会导致一些安全问题,因此应该谨慎使用,并确保对输入参数进行适当的验证和过滤。