繁体   English   中英

Linq-内存连接与EF连接

[英]Linq - In memory join vs EF Join

使用EF 6和SQL 2014。

假设您有一个索引正确且标准化的数据库。 将实体拉入内存然后在IEnumerables上执行联接还是让EF通过IQueryable联接是“更好”的选择?

更好->更快的执行时间,更少的数据库读取,内存使用。

内存示例:

using (var context = myDbContext())
{
    var table1 = await context.Table1.ToListAsync();
    var table2 = await context.Table2.ToListAsync();
    var table3 = await context.Table3.ToListAsync();

    var resultSet = table1
        .Join(table2, t1 => t1.Id, t2 => t2.Table1Id, (t1,t2) => new {t1, t2})
        .Join(table3, x => x.t2.Table2Id, t3 => t3.Table2Id, (x, t3) => new { x.t1, x.t2, t3})
        .ToList();
}

示例EF:

using (var context = myDbContext())
{
    var resultSet = await context.Table1
        .Join(context.Table2, t1 => t1.Id, t2 => t2.Table1Id, (t1,t2) => new {t1, t2})
        .Join(context.Table3, x => x.t2.Table2Id, t3 => t3.Table2Id, (x, t3) => new { x.t1, x.t2, t3})
        .ToListAsync();
}

您怎么知道一辆汽车是否比另一辆汽车快? 开车他们两个并比较时间。

通常 ,数据库在连接数据方面要比内存中的Linq更有效(由于预先计算的索引,哈希等),但是肯定会出现内存中的速度更快的情况。 但是,当您不将所有数据都拉到内存中时,通过网络传输较少的数据所带来的好处可能会比连接中的任何性能改进产生更大的影响。

因此,没有确切的答案。 开始的东西,由之前测量的时间和修改后的作品 ,然后重点的性能改进。

执行数据库查询的较慢部分之一是将数据从DBMS传输到本地进程。 因此,明智的做法是限制要传输到您的流程的数据量。 仅传输您实际打算使用的数据。

因此,如果您查询“教师与学生”,您将知道教师的ID将等于in every学生的外键“ TeacherId”。 那么,如果您已经知道值的话,为什么要为老师的1000名学生中的每位学生传送此外键?

让DBMS执行查询的另一个原因是因为数据库中的软件已经过优化,可以执行查询。 如果DBMS为查询创建了一个临时表,并且检测到新查询需要相同的临时表,那么即使查询来自其他进程,智能DBMS也会重用该临时表。

智能DBMS将检测到某些索引比其他索引更频繁地使用,并将它们保留在内存中,而不是一直从磁盘读取它们。

因此,DBMS具有各种技巧来加快查询的执行速度。

您可以通过以下方法查看此技巧的帮助:连续执行两次查询,并查看第二个查询的执行速度比第一个查询快。 这也是您无法衡量让给定查询由DBMS执行还是在本地内存中执行更快的原因 ,如一些建议。

唯一正确的方法是,在较长的时间段内(几分钟,如果不是几小时),使用大量执行这些查询的流程来评估选择的策略。 您肯定会知道的一件事是,执行AsEnumerable查询不能从其他人执行的查询中受益。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM