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

 

 

 

   

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM