简单优化实现大数据量的重复判断和导入
- 起因
- 业务如下,有一个数码表,数码是主键,另外还有如导入时间、数码层级、产品编号、产品名称、数码状态等相关字段,但只有数码是主键,无其它索引
- 要求上传文本文件并导入数码表(文本文件只包含数码信息,一行一个数码),导入的同时将相关信息也写入数码表(相关信息比较固定,可忽略)
- 导入的过程中需判断数码的格式,比如必须全数字或长度小于某个数,还需要判断数码是否重复
- 文本文件包含的数码一般为几十万行,也有几百万行的情况
- 需解决问题
- 文本文件一般为几十M到几百M,必须修改asp.net的默认配置才能上传
- 由于数据量比较大,判断数码是否存在及写入数码都需要花费大量的时间和资源
- 步骤
- 一开始想通过asp.net异步上传方式,虽然经测试功能可以实现,但是过程不可控,比如asp.ne对多线程的调配及使用,使用线程会不会出问题,因为没有时间进行充分验证,决定放弃。
- 换个思路,由于数据量比较大,处理一个文本文件有时需要几十分钟甚至以小时计算,用户对实时性要求不高。所以决定,asp.net前端只负责文件上传,文件的处理由winform程序开多线程执行
- winform处理的过程中需要两个问题,一是判断数码是否存在、二是将数码信息写入数码表。目前两个问题都是按照分批执行进行,比如有10万数码需要判断是否存在,则每次使用in查询700个数码(数码是主键,使用in查询会走索引,但是in每次查询的数量有限制),写入数码一般每次写入5w条,如果有100w数码,只用写入20次
- 结论
- 以上方法只是稍微提高了些效率,但是没有从根本上改变性能。那位有好的建议,欢迎指教!
- 解决上传文件限制的方法(修改配置文件)
i. Configuration节点下
<system.webServer>
<security>
<requestFiltering>
<!--单位为字节 maxAllowedContentLength-->
<requestLimits maxAllowedContentLength="2097151000"/>
</requestFiltering>
</security>
</system.webServer>
ii. System.web下修改节点HttpRuntime为
<!--单位为KB maxRequestLength-->
<httpRuntime maxRequestLength="2097151" executionTimeout="3600" useFullyQualifiedRedirectUrl="true" />
- 批量操作
int pageCount = 700;
int yeshu = listCode.Count / pageCount; //页数
int yushu = listCode.Count % pageCount; //余数
for (int i = 1; i <= yeshu; i++)
{
int startIndex = (i - 1) * pageCount;
var listYeshu = listCode.Skip(startIndex).Take(pageCount).ToList();
//批量处理每页的数据
}
if (yushu > 0)
{
var listYushu = listCode.Skip(yeshu * pageCount).Take(yushu).ToList();
//批量处理剩余的数据
}