由于View重新计算,LinQ查询的持续时间很长

时间:2010-09-22 09:08:46

标签: linq performance view entity-framework-4

我在数据库中创建了一个View,它让我能够在这个时间点表示组织结构。实际上,我在这个视图中使用了一个getdate()。我已经在我的edmx中导入了视图,并根据此视图编写了查询。大多数查询将视图与表连接并返回DTO。当我在SQL分析器中对它们进行分析时,这些查询工作正常并且速度很快(200毫秒)。

当我在联接表和视图上执行分组时,持续时间会更长。奇怪的是,当我执行LinQ查询时,持续时间很长,但是当我在SQL Server Management Studio中自己执行生成的查询时,它真的很快。我已经确定这不是由已经计算的缓存或执行计划引起的。 LinQ查询还为我提供了大量的读取和写入,而通过SQL Mgmt Studio进行的查询不会给我写入任何写入和更少的读取。

我们假设在通过LinQ执行查询时需要重新计算视图,而不是在通过SQL Mgmt Studio执行查询时。

我尝试过的另一种方法是在数据库中创建存储过程。此存储过程执行与LinQ生成的完全相同的查询。我已经在edmx中映射了这个存储过程。当我再次通过LinQ调用存储过程时,持续时间很长(7000毫秒)并且有大量的读写操作。当我通过SQL Mgmt Studio执行它时,持续时间是预期的(200ms),几乎没有读取和写入。

有什么建议吗? 谢谢

1 个答案:

答案 0 :(得分:0)

听起来管理工作室正在进行某种查询计划优化,LINQ无法执行,因为它执行一系列单独的命令。

我建议的是尝试将一组合理的记录带入内存并在那里进行连接。这很容易做到。

说你有这个问题:

var pcs =
    from p in dc.People
    join c in dc.Colors on p.FavColor equals c.Name
    where p.Name == "James"
    select new { p.Name, c.ColorId };

这将生成一系列SQL查询,这可能会导致您遇到的延迟类型。

所以试试这个:

var pcs =
    from p in dc.People.Where(x => x.Name == "James").ToArray()
    join c in dc.Colors.ToArray() on p.FavColor equals c.Name
    select new { p.Name, c.ColorId };

这应该将查询减少到一个或两个,并且要快得多。您只需要确保这不会尝试将50万条记录加载到内存中。如果发生这种情况,您的性能问题将从数据库转移到内存。

我希望这会有所帮助。