C# 使用EF Core快速读取数千个对象
我正在使用EF core从SQLite读取40000个小对象/行,这需要18秒,这对于我的UWP应用程序来说太长了。 当这种情况发生时,单个内核上的CPU使用率达到100%,但磁盘读取速度约为1%C# 使用EF Core快速读取数千个对象,c#,asp.net,.net,sqlite,entity-framework-core,C#,Asp.net,.net,Sqlite,Entity Framework Core,我正在使用EF core从SQLite读取40000个小对象/行,这需要18秒,这对于我的UWP应用程序来说太长了。 当这种情况发生时,单个内核上的CPU使用率达到100%,但磁盘读取速度约为1% var dataPoints = _db.DataPoints.AsNoTracking().ToArray(); 没有AsNoTracking()所需的时间甚至更长 DataPoint是一个具有一些基本属性的小型POCO。我正在加载的数据总量为4.5 MB public class Da
var dataPoints = _db.DataPoints.AsNoTracking().ToArray();
没有AsNoTracking()
所需的时间甚至更长
DataPoint
是一个具有一些基本属性的小型POCO。我正在加载的数据总量为4.5 MB
public class DataPointDto
{
[Key]
public ulong Id { get; set; }
[Required]
public DateTimeOffset TimeStamp { get; set; }
[Required]
public bool trueTime { get; set; }
[Required]
public double Value { get; set; }
}
问题:是否有更好的方法加载这么多的对象,或者我是否被这种性能水平所困扰
有趣的事实:x86需要11秒,x64需要18秒优化代码可以节省一秒钟的时间。使用
Async
将执行时间推到30秒 您可以使用不同的技术加载所有项目
您可以创建自己的逻辑,在用户滚动ListView时加载部分数据(我猜您正在使用它)
幸运的是,UWP是实现这一技术的简单方法。
增量荷载
请参阅文档和示例
大多数答案遵循加载较少数据的常识,但在某些情况下,例如在这里,您必须绝对积极地加载大量实体。那我们怎么做呢 性能不佳的原因 这次手术要花这么长时间是不可避免的吗? 嗯,不是。我们只从磁盘加载了1兆字节的数据,性能低下的原因是数据被分割到了40000个小实体中。数据库可以处理这个问题,但实体框架似乎很难设置所有这些实体、更改跟踪等。如果我们不打算修改数据,我们可以做很多事情 我试了三件事 原语 只加载一个属性,就可以得到一个原语列表
List<double> dataPoints = _db.DataPoints.Select(dp => dp.Value).ToList();
此操作需要1.2秒,而通常检索相同数量的数据需要18秒
多元组
我发现在我的例子中,使用元组而不是匿名类型稍微提高了性能,以下查询的执行速度大约快了30%:
var query = db.DataPoints.Select(dp => Tuple.Create(dp.sensorID, dp.TimeStamp, dp.Value));
其他方式
对2600万条记录(1条datetime、1条double、1条int)进行性能测试,EF Core 3.1.5:
- 接受答案中建议的匿名类型或元组=关于 20秒,1.3GB内存
- 结构=大约15秒,0.8GB内存
var query = db.DataPoints.Select(dp => Tuple.Create(dp.sensorID, dp.TimeStamp, dp.Value));