我目前正在解析一个有15.000多行的CSV文件。我需要将它们全部插入到我的数据库中,但是每一行都包含了需要插入到多个条目中的数据。
我的问题是,我需要检查每一行的数据是否已经存在于我的数据库中,如果不存在,我就在最后用BulkInsert插入。
但是,如果数据已经存在,检查每一行需要花费很多时间(entites.FirstOrDefault(...))...。我的意思是说,检查数据是否存在 "只需要30-50ms",但是要做15.000+次,整个操作要花好几分钟。
你有什么建议吗?
首先,你可以批量插入并检查约束条件(如唯一键约束)。https:/docs.microsoft.comen-usdotnetapisystem.data.sqlclient.sqlbulkcopyoptions?view=netframework-4.8。
因此,如果.csv中的一些id在db中也是唯一的,你可以用它来做一个批量插入,检查重复的键。我知道我认为当使用这个操作时,如果在源和汇中发现了重复,那么这个操作就会完全失败,但也可能是bulkinsert只插入了unqiue的值,而检查是以行为基础的。如果这适用于你的使用情况,应该值得研究。
当处理大量数据时,最好使用系统的最原始版本,sql服务器也不例外。所以尽量直接处理数据库引擎而不是EF。
说了一些你可以尝试的东西。
CsvImportStaging
这将是您的目标表的副本CsvImportStaging
CsvImportStaging
到您的源值*。TRUNCATE
的 CsvImportStaging
桌子如果你要处理多个生产者和消费者,请确保在暂存表和目标表上应用适当的锁,以使整个过程变得原子化。
* 再一次使用直接查询,而不是使用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。