简单优化实现大数据量的重复判断和导入

 
 
  1. 起因
    1. 业务如下,有一个数码表,数码是主键,另外还有如导入时间、数码层级、产品编号、产品名称、数码状态等相关字段,但只有数码是主键,无其它索引
    2. 要求上传文本文件并导入数码表(文本文件只包含数码信息,一行一个数码),导入的同时将相关信息也写入数码表(相关信息比较固定,可忽略)
    3. 导入的过程中需判断数码的格式,比如必须全数字或长度小于某个数,还需要判断数码是否重复
    4. 文本文件包含的数码一般为几十万行,也有几百万行的情况
  2. 需解决问题
    1. 文本文件一般为几十M到几百M,必须修改asp.net的默认配置才能上传
    2. 由于数据量比较大,判断数码是否存在及写入数码都需要花费大量的时间和资源
  3. 步骤
    1. 一开始想通过asp.net异步上传方式,虽然经测试功能可以实现,但是过程不可控,比如asp.ne对多线程的调配及使用,使用线程会不会出问题,因为没有时间进行充分验证,决定放弃。
    2. 换个思路,由于数据量比较大,处理一个文本文件有时需要几十分钟甚至以小时计算,用户对实时性要求不高。所以决定,asp.net前端只负责文件上传,文件的处理由winform程序开多线程执行
    3. winform处理的过程中需要两个问题,一是判断数码是否存在、二是将数码信息写入数码表。目前两个问题都是按照分批执行进行,比如有10万数码需要判断是否存在,则每次使用in查询700个数码(数码是主键,使用in查询会走索引,但是in每次查询的数量有限制),写入数码一般每次写入5w条,如果有100w数码,只用写入20次
  4. 结论
    1. 以上方法只是稍微提高了些效率,但是没有从根本上改变性能。那位有好的建议,欢迎指教!
    2. 解决上传文件限制的方法(修改配置文件)

      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" />

    3. 批量操作
      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();
          //批量处理剩余的数据
      }




posted @ 2013-06-17 15:06    阅读(1311)  评论(0编辑  收藏  举报