Linq查询超级慢?

时间:2011-03-25 18:33:55

标签: .net linq ado.net entity-framework-4

我从sql profiler复制了linq构建的sql查询,这里有什么令人讨厌的事情:

  1. 它的前缀为select ..columnNames ..(select ...columnNames .. from(select view from view from view) 注释:此处的2个选择语句是不必要的。

  2. 此查询需要14秒才能执行

  3. 当我删除最后一行,包含所有参数,如@ p_ linq _0 ..并在where条件中填充param值并执行完全相同的动态查询需要1秒或更少。即使从sql studio执行此查询也需要0秒。这是linq的蹩脚。

  4. 我可能会将此移至存储过程,但我现在害怕使用linq

    经过进一步研究后我发现:

    查询1:

    exec sp_executesql N'SELECT * from TableView WHERE Id = @Id', N'@Id int', @Id = 1
    

    查询2:

    exec sp_executesql N'SELECT * from TableView WHERE Id = 1'
    

    查询1需要12秒,查询2需要0秒。这解释了为什么linq查询很慢。所以现在,这是否意味着我应该总是使用存储过程或者我错过了什么?

    为什么Microsoft无法修复Linq查询构建,解析该字符串并替换param值而不是将这些params作为参数传递给sp_executesql

    是多么困难

3 个答案:

答案 0 :(得分:6)

我和你在一起。我的意思是,你可能会发现你发现这种灾难性性能的原因并找到补救措施。但实际上,这种事情发生在Linq to SQL上,并花费额外的时间来优化你的Linq语句,以便SQL查询在后端类型上的性能更加失败。 Linq应该让事情变得更容易。

我个人使用Linq-to-SQL或Entity Framework对单个记录执行CRUD操作。然后使用任何大的SELECT语句,我将简单地编写一个存储过程,就像我一直在做的那样。这似乎是生产力和性能之间的良好折衷,对我来说效果很好。

编辑: 事实上,实体框架的人们预料到了这一点。实体框架与存储过程非常相似。你可以add a stored proc to your Entity Framework model获得所有那种强烈类型的善良。然后你可以从代码中调用那个存储过程。

答案 1 :(得分:0)

您应该构建Where谓词,动态取出特定于应用程序的daysRange 像这样

var query = from v in tableView
            where v.Id == Id
            orderby v.RDate descending
            select v;

if(!daysRange.Equals("All"))
{
  query = query.Where(v => v.RdDate >= fromDate && v.RDate <= toDate);
}

query.ToList();

答案 2 :(得分:0)

这样可行。

ParameterExpression parameterExpression = Expression.Parameter(typeof(TableView), "v");
Expression equalsExpression = Expression.Equal(Expression.Property(parameterExpression, "Id"), Expression.Constant(Id));
Expression<Func<TableView, bool>> predicate = Expression.Lamda<Func<TableView, bool>>(equalsExpression, parameter);

var query = from v in tableView
            orderby v.RDate descending
            select v;

if(!daysRange.Equals("All"))
{
  query = query.Where(v => v.RdDate >= fromDate && v.RDate <= toDate);
}

query.Where(predicate).ToList();