EF核心CSV上传检查数据是否存在需要大量时间

问题描述 投票:0回答:1

我目前正在解析一个有15.000多行的CSV文件。我需要将它们全部插入到我的数据库中,但是每一行都包含了需要插入到多个条目中的数据。

我的问题是,我需要检查每一行的数据是否已经存在于我的数据库中,如果不存在,我就在最后用BulkInsert插入。

但是,如果数据已经存在,检查每一行需要花费很多时间(entites.FirstOrDefault(...))...。我的意思是说,检查数据是否存在 "只需要30-50ms",但是要做15.000+次,整个操作要花好几分钟。

你有什么建议吗?

.net entity-framework asp.net-core
1个回答
1
投票

首先,你可以批量插入并检查约束条件(如唯一键约束)。https:/docs.microsoft.comen-usdotnetapisystem.data.sqlclient.sqlbulkcopyoptions?view=netframework-4.8。

因此,如果.csv中的一些id在db中也是唯一的,你可以用它来做一个批量插入,检查重复的键。我知道我认为当使用这个操作时,如果在源和汇中发现了重复,那么这个操作就会完全失败,但也可能是bulkinsert只插入了unqiue的值,而检查是以行为基础的。如果这适用于你的使用情况,应该值得研究。

当处理大量数据时,最好使用系统的最原始版本,sql服务器也不例外。所以尽量直接处理数据库引擎而不是EF。

说了一些你可以尝试的东西。

  1. 创建一个叫 CsvImportStaging 这将是您的目标表的副本
  2. 将.csv文件的数据批量导入到 CsvImportStaging
  3. 现在把所有的唯一值从 CsvImportStaging 到您的源值*。
  4. TRUNCATECsvImportStaging 桌子

如果你要处理多个生产者和消费者,请确保在暂存表和目标表上应用适当的锁,以使整个过程变得原子化。

* 再一次使用直接查询,而不是使用efe.g.这样的查询。

INSERT INTO Table2(Id) SELECT WHERE Id NOT IN(SELECT Id FROM Table1);

这将需要一些实验来确定什么样的查询是最有效的.我想你也可以用(OUTER)JOIN 而不是 WHERE .. IN 因为加入的速度可以相当快.我也看到了。MERGE 语句在transact-sql中,但我还没有使用它。

https:/docs.microsoft.comen-ussqlt-sqlstatementsmerge-transact-sql?view=sql-server-ver15。

© www.soinside.com 2019 - 2024. All rights reserved.