C#序列化大型数据集

本文关键字:数据集 大型 序列化 | 更新日期: 2023-09-27 18:22:14

我正试图将数据从Microsoft SQL数据库移动到Elasticsearch中。我使用EF 6生成模型(从数据库中代码优先),并使用NEST将对象序列化为Elasticsearch。

如果我使用Lazy加载,它可以很好地工作,但速度慢得令人难以置信(太慢了,无法使用)。如果我通过添加以下行切换到Eagle加载:

public MyContext() : base("name=MyContext")
{
    this.Configuration.LazyLoadingEnabled = false;
}

像这样序列化:

ElasticClient client = new ElasticClient(settings);
var allObjects = context.objects
    .Include("item1")
    .Include("item2")
    .Include("item2.item1")
    .Include("item2.item1.item");
client.IndexMany(allObjects);

在序列化发生之前,我最终会得到一个System.OutOfMemoryException(所以只需加载数据)。我有大约2.5 GB的可用内存,我们谈论的是数据库中的11.0万个项目。

我尝试过对数据进行排序,然后使用Skip和Take一次只序列化一定数量的对象,但在内存耗尽之前,我只成功地将60000个对象插入到Elasticsearch中。垃圾收集器似乎没有释放足够的内存,即使我在将一定数量的对象插入Elasticsearch后显式调用了它。

有没有一种方法可以加载特定数量的对象?还是序列化大型数据集的另一种方法?

C#序列化大型数据集

事后看来,这是一个愚蠢的错误。通过这样做,我成功地实现了我的目标:

int numberOfObjects;
using (var context = new myContext())
{
    numberOfObjects = context.objects.Count();
}
for (int i = 0; i < numberOfObjects; i += 10000)
{
    using (var context = new myContext())
    {
        var allObjekts = context.objects.OrderBy(s => s.ID)
            .Skip(i)
            .Take(10000)
            .Include("item1")
            .Include("item2")
            .Include("item2.item1")
            .Include("item2.item1.item");
            client.IndexMany(allObjekts);
    }
}

这使得Gargage收集器能够完成它的工作,因为上下文被包裹在for循环中。我不知道是否有更快的方法,我可以在大约400秒内在Elasticsearch中插入大约100000个对象。