LINQ-to-SQL中的“Order By”导致性能问题

时间:2010-02-14 15:06:04

标签: .net linq-to-sql tsql sql-server-ce

我已经开始在我的C#应用​​程序中编写一个方法,该方法可以从包含大约2000个名称的表中返回一个有序的名称子集,该名称从第100个名称开始并返回接下来的20个名称。

我正在这样做,所以我可以在我的UI中填充WPF DataGrid并进行一些自定义分页。我一直在使用LINQ to SQL,但遇到了这个长时间执行的查询,所以我正在检查LINQ查询正在使用的SQL(下面的查询B)。

查询A运行良好:

SELECT TOP (20) 
[t0].[subject_id] AS [Subject_id],
[t0].[session_id] AS [Session_id], 
[t0].[name] AS [Name]

FROM [Subjects] AS [t0]
WHERE (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT TOP (100) [t1].[subject_id]
        FROM [Subjects] AS [t1]
        WHERE [t1].[session_id] = 1
        ORDER BY [t1].[name]
        ) AS [t2]
    WHERE [t0].[subject_id] = [t2].[subject_id]
    ))) AND ([t0].[session_id] = 1)

查询B需要40秒:

SELECT TOP (20) 
[t0].[subject_id] AS [Subject_id],
[t0].[session_id] AS [Session_id], 
[t0].[name] AS [Name]

FROM [Subjects] AS [t0]
WHERE (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT TOP (100) [t1].[subject_id]
        FROM [Subjects] AS [t1]
        WHERE [t1].[session_id] = 1
        ORDER BY [t1].[name]
        ) AS [t2]
    WHERE [t0].[subject_id] = [t2].[subject_id]
    ))) AND ([t0].[session_id] = 1)
ORDER BY [t0].[name]

当我将 ORDER BY [t0]。[name] 添加到外部查询时,会减慢查询速度。

如何改进第二个查询?


这是我的LINQ东西尼克

int sessionId = 1;
int start = 100;
int count = 20;

//  Query subjects with the shoot's session id
var subjects = cldb.Subjects.Where<Subject>(s => s.Session_id == sessionId);

//  Filter as per params
var orderedSubjects = subjects
        .OrderBy<Subject, string>(
                    s => s.Col_zero 
                    );                

var filteredSubjects = orderedSubjects
        .Skip<Subject>(start)
        .Take<Subject>(count);

3 个答案:

答案 0 :(得分:4)

[Subjects].[name]上缺少索引?

答案 1 :(得分:0)

如果您可以在LINQ查询中更改.OrderBy的顺序,则可能会获得一些性能。即您查询分页数据(无序),然后执行OrderBy。这将注入您的查询A,以对内存数据进行排序。

答案 2 :(得分:0)

您的查询会选择TOP 20,但当您向ORDER BY查询添加TOP时,则表示必须按{{1}对整个表格进行排序然后逐行执行此子查询。因此,虽然更改可能看起来无害,但第二个查询实际上非常不同,因为它现在要处理的行数超过20行。这在性能方面很糟糕,如果你在Name列上没有索引,那就更糟了。

如果您尝试进行分页,可能需要查看this question。虽然这是你在多用户数据库中永远不会做的事情,但是SQL Server CE是单用户的,对于分页查询,它通常(几乎总是)更快地使用表直接访问这种类型的东西或者可以向后搜索的静态游标(Name)。