C#EntityFramework获取数据的有效方式(OrderBy+;Distinct)
我想用最新的登录时间从DB中获得不同的用户。我的代码是有效的,但芬兰语大约需要20秒。我可以优化我的代码吗C#EntityFramework获取数据的有效方式(OrderBy+;Distinct),c#,entity-framework,C#,Entity Framework,我想用最新的登录时间从DB中获得不同的用户。我的代码是有效的,但芬兰语大约需要20秒。我可以优化我的代码吗 var usersFromDb = _Context.Users .OrderByDescending(u => u.Time) .DistinctBy(u => u.ID).ToList(); 型号: public class User { public int ID { get; set; } public stri
var usersFromDb = _Context.Users
.OrderByDescending(u => u.Time)
.DistinctBy(u => u.ID).ToList();
型号:
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public int Client { get; set; }
public DateTime Time { get; set; }
}
这个表有大约100k条记录,除非我遗漏了什么,否则用户应该已经有了唯一的Id,所以distinct是多余的 我希望SQL Optimizer知道,如果是聚集索引,您可以尝试删除它 是否需要返回所有用户?你在使用延迟加载吗?您可能也在回拉客户机数据,因此可能需要检查SQL Server profiler以了解发生了什么 您也可以只返回所需的字段:
var usersFromDb = _Context.Users
.Select(u => new MyUser
{
Id = u.ID,
Name = u.Name,
Time = u.Time
}).
.OrderByDescending(u => u.Time)
.ToList();
您应该为
Time
字段添加非聚集索引,以优化OrderBy操作。例如,您可以像这样更改模型
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public int Client { get; set; }
[Index]
public DateTime Time { get; set; }
}
并在下一步将迁移应用到DB。另一种方法是,您可以在数据库中创建索引,而无需更改EF模型,只需执行下一个sql查询
CREATE INDEX IDX_Time ON Users (Time);
在排序列上定义索引可以提高性能结果
由于
ID
不是主键,您应该从两列中创建一个覆盖索引,以最大限度地提高查询性能
CREATE INDEX IDX_Time ON Users (Time, ID);
您可以附加您的模型吗?您是否考虑过在表中添加相应的索引?ID字段是表中的主键?如果使用的
DistinctBy
方法来自MoreLINQ,则它将在内存中执行。您可能需要使用GroupBy
+OrderDescending
+FirstOrDefault
,以便在数据库中获取整个内容。另外,如果ID
不是PK,那么什么是PK(EF不能在没有PK的情况下工作)?这听起来可能很愚蠢,你可能认为它没有意义,但在这种情况下,同一个ID可以出现多次(这就是我需要distnict的原因)。我不是这个数据库的设计者。此表有大约100k条记录。然后您的Id需要一个索引以改进访问。您还可以尝试按Id分组,并选择最长日期。在任何需要快速尝试不同Linq的情况下,最好的做法是安装LinqPad。让它成为你的朋友,它会很好地为你服务。通过向时间列添加索引,响应时间从~20秒减少到~10秒。非常感谢。