C# LINQ语句的性能是否比SQL语句差?

C# LINQ语句的性能是否比SQL语句差?,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,在一些场景中,我观察到,LINQ语句的性能(通过SQL Server Profiler测量)不到同一查询的SQL语句性能的一半。这种情况是否总是或可能是由于LINQ语句的构造不当 以下是SQL查询及其LINQ版本的一个示例,其中存在一个主要的性能差异:- SQL: SELECT * FROM persDetails p INNER JOIN level q ON p.levelId = q.id AND q.level = 1 WHERE date = (SELECT max(date) fr

在一些场景中,我观察到,LINQ语句的性能(通过SQL Server Profiler测量)不到同一查询的SQL语句性能的一半。这种情况是否总是或可能是由于LINQ语句的构造不当

以下是SQL查询及其LINQ版本的一个示例,其中存在一个主要的性能差异:-

SQL: 
SELECT * FROM persDetails p
INNER JOIN level q
ON p.levelId = q.id AND q.level = 1
WHERE date = (SELECT max(date) from persDetails)

LINQ:
var result = from p in persDetails
             join  q in level on p.levelId equals q.level
             where q.level = 1
             join r in (from n in persDetails group n by n.departmentId into g select new { maxDate = g.Max(t => t.date)})
             on p.date equals r.maxDate
             select p;
表:详情

表:水平

预期结果


然后,LINQ语句被转换为普通SQL查询。您可以使用SQLServerProfiler查看LINQ生成的查询,并将其与手工编写的查询进行比较。通常,LINQ查询的性能与手工编写的一样好,但并不总是如此——它是一个自动生成的查询,不能总是完美地满足任何需求

谈到您的查询,它们只是不同,可能会导致不同的结果。LINQ查询比SQL查询复杂得多——它有更多的选择和联接,并使用联接查找最大日期。它的性能一定要差一些

以下LINQ查询完全类似于SQL查询:

var result = from p in persDetails
             join q in level on p.levelId equals q.level
             where q.level == 1 and p.date == persDetails.Max(x => x.date)
             select p;

它将导致类似的查询,并将花费相同的时间执行

然后,LINQ语句被转换为普通SQL查询。您可以使用SQLServerProfiler查看LINQ生成的查询,并将其与手工编写的查询进行比较。通常,LINQ查询的性能与手工编写的一样好,但有时不行。它是自动生成的,不能完全满足任何要求。顺便说一句,LINQ查询比SQL查询复杂得多,有更多的选择和连接。它的性能一定要差一些。您的SQL查询也只使用了
max(date)
,没有分组,这两个查询可能会导致不同的结果。@YeldarKurmangaliyev我在探查器中看到了转换后的SQL查询,它与我编写的查询不同。我想不出如何将上面的sql转换成更好的LINQ代码。它正在通过两个连接转换为SQL@YeldarKurmangaliyev您能推荐上面SQL的简化LINQ版本吗。感谢您可以使用LINQ和手写SQL获得好的或差的性能。这取决于您如何编写每个查询。无论哪种方法,您都应该分析两种实现的性能,包括生成的SQL。简单地让
和p.date=persDetails.Max(x=>x.date)
不起作用吗?而不是两次往返于database@Rob我不确定,但我已经测试过了,应该可以用了。有时候,我想知道这些LINQ提供者有多聪明:)谢谢你们的纠正。@YeldarKurmangaliyev,@Rob非常感谢你们两位。建议的LINQ查询无疑带来了性能改进。但是,原始SQL的运行时间为
CPU时间=0ms,运行时间=8ms
,而LINQ查询生成的SQL语句的运行时间为
CPU时间=16ms,运行时间=8ms
。两者都已在SQL Management Studio中运行。
|id | LevelName | level |
|---|-----------|-------|
| 1 |   CEO     |  1    |
| 2 |   CTO     |  1    |
| 3 |General Mgr|  2    |
|id | persID | name | salary |    date   | LevelId |
|---|--------|------|--------|-----------|---------| 
| 1 |  1     | John | $500   |2017/03/01 | 1       |
| 2 |  3     | Alice| $550   |2017/03/01 | 1       |
var result = from p in persDetails
             join q in level on p.levelId equals q.level
             where q.level == 1 and p.date == persDetails.Max(x => x.date)
             select p;