linq 大数据 sql 查询及分页优化

前提:

  需要nuget   PredicateLib   0.0.5;

  SqlServer  2008R2 (建议安装 64 位);

  .net 4.5 或以上;

  当前电脑配置: I7 4核  3.6GHZ,8G 内存 (办公电脑 ,win10 64位)

描述:

  在实际项目中我们会遇到多个表关联查询数据,并进行分页操作;当数据量很大的时候如(500万或以上)的时候,分页很吃力,特别还需要一些模糊查询,排序的时候会导致很慢;

  本文章主要解决分页及多个数据表关系查询速度慢的问题:

解决办法及优化过程:

  1、通常我们对 数据库的优化莫过于索引,储存过程等;

  2、能使用一条Sql 语句查询的话,不要使用多条语句(学习使用 linq 语法);

  3、尽量少使用 in ('.....') 多个值;经测试超过 5万个 in 的时候会提示内存不足异常;

  4、order 的使用很是奇葩,原本用 order Id(主键),反而查询非常慢,而且 Cpu 使用一下子 100%,换成别的字段就完全没压力;(暂时无法理解,在出现问题后可尝试改变 order)

  5、尽量 select 少的字段,在实际中遇到 分页的时候,先 select 出 Id,然后在通过 Id 去查询完整数据,会比直接查询完整要快 N 倍;

    如通过两条语句查询出大数据的时候:var ids =  select top 10 Id from ViewTable; 

                     var datas =  select * from ViewTable where Id in (ids); 

结合表示式生成分页查询扩展(完美优化): 

   非常实用的硬代码,在大数据分页的时候性能优越:

   主要原理跟上面 第 5点 一样,但优化只通过一次查询出完整数据;

  缺点: 每页的数据量建议不要太大,比如:每页1万

        /// <summary>
        /// 执行分页        
        /// 性能比较好
        /// </summary>
        /// <typeparam name="T">实体类型<peparam>
        /// <param name="source">数据源</param>    
        /// <param name="orderBy">排序字符串</param>
        /// <param name="pageIndex">分页索引</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="idSelector">Id选择器</param>
        /// <returns></returns>
        public static async Task<PageInfo<T>> ToPageAsync<T, TId>(this IQueryable<T> source, string orderBy, int pageIndex, int pageSize, Expression<Func<T, TId>> idSelector)
            where T : class
            where TId : class
        {
            source = source.Where(Predicate.Create(idSelector, null, Operator.NotEqual));
            int total = await source.CountAsync();
            var inc = total % pageSize > 0 ? 0 : -1;
            var maxPageIndex = (int)Math.Floor((double)total / pageSize) + inc;
            pageIndex = Math.Max(0, Math.Min(pageIndex, maxPageIndex));

            var idQuery = source.OrderBy(orderBy).Skip(pageIndex * pageSize).Take(pageSize).Select(idSelector);
            var datas = await source.Join(idQuery, idSelector, item => item, (item, id) => item).OrderBy(orderBy).ToArrayAsync();

            var page = new PageInfo<T>(total, datas) { PageIndex = pageIndex, PageSize = pageSize };
            return page;
        }

 

 

 

   

  

 

posted @ 2019-07-08 11:42  皓月青峰  阅读(1311)  评论(0编辑  收藏  举报