与LINQ to SQL生成的SQL相比,LINQ to Entities生成的SQL效率低下?

时间:2010-11-19 16:02:02

标签: sql linq-to-sql linq-to-entities

我们开始将项目从带有存储过程的VS2008迁移到VS2010,实体框架4作为ORM。

现在我不得不做一个相当复杂的LINQ查询来从我们的数据库中获取数据。我通常首先尝试使用LINQPad找出LINQ查询(很棒的工具顺便说一句!)。

现在我注意到,与LINQ to SQL相比,LINQ to Entities生成的SQL是可怕的,这产生了类似于之前存储过程的SQL语句。 L2E查询有如此多的嵌套SELECT和INNER JOINS,只是看着它就伤到了我的脑袋!

这让我很好奇,我选择了另一个相当复杂的LINQ查询,并将LINQ to Entites生成的SQL与LINQ to SQL生成的SQL进行了比较。结果类似,L2E SQL非常糟糕,而且很可能非常低效(我没有对它进行基准测试,但对我来说,通过查看SQL语句很清楚)

很抱歉我目前无法提供一些示例查询,但如果兴趣足够高,我可以设置一个虚拟数据库并创建类似于我们使用的查询(模糊我们的查询和表格会使查询不可读且毫无意义)

那么您对实体框架的体验是什么?没有人注意到可怕的SQL语句或大多数人都不在乎吗?我错过了一些我应该知道的关于L2E的基本内容吗?

现在我非常遗憾我们选择了实体框架而不是LINQ to SQL。

修改

所以我做了一些基准和WOW,我很惊讶!我将生成的SQL语句放入SQL Server Management Studio的查询窗口中,并多次执行每个查询。以下是在WHILE循环中执行查询的平均结果1次,10次和100次。

1 time:
  LINQ to SQL: 440ms
  LINQ to Entities: 240ms

10 times:
  LINQ to SQL: 2900ms
  LINQ to Entities: 910ms

100 times:
  LINQ to SQL: 31600ms
  LINQ to Entities: 7000ms

我真的很惊讶!

我的下一个测试是创建一个简单的C#程序来生成和执行SQL语句。为方便起见,我使用了LINQpad。对于每个测试,我在LINQPad中使用LINQ to SQL和LINQ to Entities数据提供程序。查询每次都完全相同。 测试程序如下所示:

void Main()
{
    var sw = new Stopwatch();

    for(int i = 0; i < 5; i++)
    {
        sw.Start();
        for(int y = 0; y < 10; y++)
        {
            ExecuteQuery();
        }
        sw.Stop();
        Console.WriteLine(string.Format("Pass {0}: {1}", i, sw.ElapsedMilliseconds));
        sw.Reset();
    }
}
private void ExecuteQuery()
{
    //here is my 'complex' linq query
    var dummy = (from p in....).ToList();
}

这次我有点失望,结果如下:

LINQ to SQL:
Run 0: 805
Run 1: 726
Run 2: 722
Run 3: 717
Run 4: 767

LINQ to Entities:
Run 0: 3031
Run 1: 3231
Run 2: 3085
Run 3: 3127
Run 4: 3148

我认为差异是由于SQL语句生成造成的?或者我完全错误的基准测试?建议?

EDIT2: 我在我们的项目中实现了LINQ查询(忘了提到该项目是一个ASP.NET MVC 3 RC Web应用程序)。我们基本上显示一个带有自定义网格的页面。使用LINQ to Entities加载网格数据大约需要300-400毫秒!使用LINQ to SQL加载数据大约需要70-80ms。这实际上与我在上面LINQPad中的测试应用程序中的结果非常相似。

过去几个小时我一直在搜索EF的性能问题,我发现初始查询存在很多问题。事实上,初始查询速度较慢,但​​只有大约200毫秒,因此第一个查询需要大约600毫秒,而每个其他后续查询需要300-400毫秒。我还读到了precompiling views with EdmGen,但它并没有什么不同。我找到了另一个blog post that compared LINQ to SQL performance with EF,结果似乎相似,尽管这是针对EF 3.5的。然后我找到了blog post about EF with heavy inheritance,但这并不适用于我的情况。

除了一百个“初始查询很慢”类型的帖子我没有找到任何与我的问题相关的内容。我的意思是,与Linq to SQL相比,我不介意性能损失,但70ms与300ms相比是一个巨大的差异!它确实会影响我们的网络应用程序的用户体验。

我要尝试的最后一件事是预编译查询。如果性能没有好转,那么我肯定会切换到LINQ to SQL(尽管生成的SQL本身确实更快!)

1 个答案:

答案 0 :(得分:2)

当你说你实际上并没有费心去衡量表现时,你就失去了我。

仅仅因为SQL看起来很糟糕,这并不意味着它的表现非常糟糕(始终如此)。

当使用Entity Framework或LINQ to SQL时,只要我的应用程序仍符合我的标准,我真的不在乎生成的语句是什么样的。只有在性能降低到可接受的水平之后,我才会对查询进行微调以获得更好的SQL。