• 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;
            }

       

      

  • 相关阅读:
    nginx+upsync+consul 构建动态nginx配置系统
    服务容错保护断路器Hystrix之六:缓存功能的使用
    consul之:ACL配置使用
    Consul之:服务健康监测
    Consul实践指导-DNS接口
    Spring 整合Mybatis实例
    ORACLE SEQUENCE 具体解释
    python高速排序
    降阶法计算行列式方法有个地方有Bug(原文也已更正,此为更正后部分)
    MyBatis在Oracle中插入数据并返回主键的问题解决
  • 原文地址:https://www.cnblogs.com/intotf/p/11150214.html
Copyright © 2020-2023  润新知