前倆天發佈了 關於PDF.NET開發框架對Mysql Sqlite PostgreSQL數據庫分頁支持的我的見解 ,說明了本人對框架的一些介紹和見解。今天咱們一塊兒思考一些問題。html
1.裝箱與拆箱sql
EntityBase.cs數據庫
1 private object[] values; 2 /// <summary> 3 /// 屬性值列表 4 /// </summary> 5 public virtual object[] PropertyValues 6 { 7 get 8 { 9 if (values == null) 10 { 11 values = new object[PropertyNames.Length]; 12 } 13 return values; 14 } 15 protected internal set { values = value; } 16 }
每一個實體類對象,通常狀況下至關於表中的一行數據。把屬性裏封裝的字段放在數組中,字段有值類型(tinyint int double...) 引用類型,爲了知足各類類型只能由object類型出廠,這樣會致使值類型頻繁進行拆箱(引用類型到值類型--get)/裝箱(值類型到引用類型--set)操做.這在必定程度上,對性能形成了損耗。數組
2.for與foreach緩存
CommonDB.cs框架
1 if (parameters != null) 2 for (int i = 0; i < parameters.Length; i++) 3 if (parameters[i] != null) 4 { 5 if (commandType != CommandType.StoredProcedure) 6 { 7 //IDataParameter para = (IDataParameter)((ICloneable)parameters[i]).Clone(); 8 IDataParameter para = parameters[i]; 9 if (para.Value == null) 10 para.Value = DBNull.Value; 11 cmd.Parameters.Add(para); 12 } 13 else 14 { 15 //爲存儲過程帶回返回值 16 cmd.Parameters.Add(parameters[i]); 17 } 18 }
使用for循環,加數組的索引器使用(每調用一次,就循環一次,能夠反編譯查看),會形成數組的重複遍歷。話很少說,看哥代碼,你懂得!ide
1 if (parameters != null) 2 { 3 foreach (IDataParameter para in parameters) 4 { 5 if (para != null) 6 { 7 if (commandType != CommandType.StoredProcedure) 8 { 9 if (para.Value == null) 10 para.Value = DBNull.Value; 11 cmd.Parameters.Add(para); 12 } 13 else 14 { 15 //爲存儲過程帶回返回值 16 cmd.Parameters.Add(para); 17 } 18 } 19 } 20 }
3.雙重鎖定 double check性能
SqlCache.csui
1 /// <summary> 2 /// 增長一項到緩存中 3 /// </summary> 4 /// <param name="key"></param> 5 /// <param name="item"></param> 6 /// <returns></returns> 7 public static bool AddToCache(string key,SqlInfo item) 8 { 9 SqlInfo Value = GetFromCache(key); 10 if (Value != null) 11 return false; 12 lock (sync_obj) 13 { 14 DictSqlCache.Add(key, item); 15 } 16 return true; 17 }
第一個if確實能減小鎖的影響,提示性能。 lock裏須要作判斷的...看代碼spa
1 /// <summary> 2 /// 增長一項到緩存中 3 /// </summary> 4 /// <param name="key"></param> 5 /// <param name="item"></param> 6 /// <returns></returns> 7 public static bool AddToCache(string key, SqlInfo item) 8 { 9 if (!DictSqlCache.ContainsKey(key))//在lock前判斷,有助於提高性能 10 { 11 lock (sync_obj)//假設2個線程同時執行到這,若是lock裏不作判斷會出問題 12 { 13 if (!DictSqlCache.ContainsKey(key)) 14 { 15 DictSqlCache.Add(key, item); 16 return true; 17 } 18 } 19 } 20 return false; 21 }
4.分頁
SqlPage.cs
1 /// <summary> 2 /// 根據主鍵的高效快速分頁之 升序分頁 3 /// </summary> 4 /// <param name="pageNum">頁碼,從1開始</param> 5 /// <param name="pageSize">頁大小,大於1</param> 6 /// <param name="filedList">字段列表</param> 7 /// <param name="tableName">表名稱</param> 8 /// <param name="PKName">主鍵名稱</param> 9 /// <param name="conditon">查詢條件</param> 10 /// <returns>返回指定頁碼的快速分頁SQL語句</returns> 11 public static string GetAscPageSQLbyPrimaryKey(int pageNum, int pageSize, string filedList, string tableName, string PKName, string conditon) 12 { 13 if (conditon == null || conditon == "") 14 conditon = "1=1"; 15 if (pageNum == 1) 16 { 17 string sqlTemplage = "Select top @pageSize @filedList from @table1 where @conditon order by @PKName desc "; 18 return sqlTemplage 19 .Replace("@pageSize", pageSize.ToString()) 20 .Replace("@filedList", filedList) 21 .Replace("@table1", tableName) 22 .Replace("@conditon", conditon) 23 .Replace("@PKName", PKName); 24 } 25 else 26 { 27 //@topNum= ((頁碼-1)*頁大小) 28 string sqlTemplage = @" 29 select top @pageSize @filedList 30 from @table1 31 where @conditon And @PKName> 32 (select max (@PKName) from 33 (select top @topNum @PKName from @table1 where @conditon order by @PKName asc) as T 34 ) 35 order by @PKName asc 36 "; 37 int topNum = (pageNum - 1) * pageSize; 38 39 return sqlTemplage.Replace("@topNum", topNum.ToString()) 40 .Replace("@pageSize", pageSize.ToString()) 41 .Replace("@filedList", filedList) 42 .Replace("@table1", tableName) 43 .Replace("@conditon", conditon) 44 .Replace("@PKName", PKName); 45 46 } 47 }
首先,要把字符串對象構造爲StringBuilder對象,用StringBuilder對象的Replace方法,這些細節和上篇也提到了,不少人會認爲這是廢話,好吧......我不說廢話了,進入重點。
看了不少分頁代碼,有not in的,rownum僞列的,limit的。但若是隻根據一列進行查詢,主鍵列或其餘值類型的列都可,這種分頁無疑是性能最高的。我的很欣賞做者的代碼。
可是,我想提一個問題,
假如tableName參數傳入的是一個viewName(視圖名稱),
而這個視圖是有10張同結構的表,或不一樣結構的表抽取意義相同的列的數據 union而成。
這個視圖數據量百萬級數據量。這麼寫能禁得住考驗嗎?
那麼該如何改進呢?
相信clever的你已經懂了,若還沒想通,那就經歷3重境界吧:
昨夜西風凋碧樹,獨上高樓,望盡天涯路。
衣帶漸寬終不悔,爲伊消得人憔悴。
而後是驀然回首...........