使用LinqDB查詢Sqlite資料庫數據,不管是大數據還是少量的數據,感覺特別耗時,尤其是首次查詢 一個含有2.7萬條數據的數據表 首次查詢: 查詢2.7萬條數據,耗時1s 查詢8條數據,也要耗時750ms 二次查詢: 查詢2.7萬條數據,耗時475ms 查詢指定的1條數據,耗時73ms 我們來嘗 ...
使用LinqDB查詢Sqlite資料庫數據,不管是大數據還是少量的數據,感覺特別耗時,尤其是首次查詢
一個含有2.7萬條數據的數據表
首次查詢:
- 查詢2.7萬條數據,耗時1s
- 查詢指定的1條數據,也要耗時750ms
二次查詢:
- 查詢2.7萬條數據,耗時475ms
- 查詢指定的1條數據,耗時73ms
我們來嘗試優化一下,使用Sql語句查詢
Sql查詢資料庫
Sql連接字元串:
1 var dbRelativePath = "Dbs\\EnglishDict.db3"; 2 var connectionString = "data source=" + System.Environment.CurrentDirectory + "\\" + dbRelativePath + ";version=3;";
Sql查詢,返回DataSet集合
1 /// <summary> 2 /// 獲得數據列表 3 /// </summary> 4 public DataSet GetList(string strWhere, string tableName) 5 { 6 StringBuilder strSql = new StringBuilder(); 7 strSql.Append("select * "); 8 strSql.Append($" FROM {tableName} "); 9 if (strWhere.Trim() != "") 10 { 11 strSql.Append(" where " + strWhere); 12 } 13 return Query(strSql.ToString()); 14 } 15 /// <summary> 16 /// 執行查詢語句,返回DataSet 17 /// </summary> 18 /// <param name="sQLString">查詢語句</param> 19 /// <returns>DataSet</returns> 20 public DataSet Query(string sQLString) 21 { 22 using (SQLiteConnection connection = new SQLiteConnection(connectionString)) 23 { 24 DataSet ds = new DataSet(); 25 try 26 { 27 connection.Open(); 28 SQLiteDataAdapter command = new SQLiteDataAdapter(sQLString, connection); 29 command.Fill(ds, "ds"); 30 } 31 catch (System.Data.SQLite.SQLiteException ex) 32 { 33 throw new Exception(ex.Message); 34 } 35 return ds; 36 } 37 }
DataSet數據集轉數據列表
1. 使用反射,映射到Entity數據類中
見 資料庫查詢 - DataTable轉Entity類型數據
1 /// <summary> 2 /// 獲得數據列表 3 /// </summary> 4 public List<CoursewareInfo> GetCoursewares() 5 { 6 DataSet ds = GetList(string.Empty, "Courseware"); 7 //通過映射,DataSet轉實體類 8 var modelList = DataTableConverter<CoursewareInfo>.ToList(ds.Tables[0]); 9 return modelList; 10 } 11 /// <summary> 12 /// 獲得數據列表 13 /// </summary> 14 public List<CoursewareInfo> GetCoursewares(string queryText) 15 { 16 var queryString = $"Name like '%{queryText}%'"; 17 DataSet ds = GetList(queryString, "Courseware"); 18 //通過映射,DataSet轉實體類 19 var modelList = DataTableConverter<CoursewareInfo>.ToList(ds.Tables[0]); 20 return modelList; 21 }
我們來看下查詢數據的性能,還是同一數據表
首次查詢:
- 查詢2.7萬條數據,耗時1612ms
- 查詢指定的1條數據,也要耗時196ms
二次查詢:
- 查詢2.7萬條數據,耗時1484ms
- 查詢指定的1條數據,耗時59ms
此方案耗時較多,應該是反射傷性能,放棄
2. 直接給數據類欄位屬性賦值
DataTable轉數據類:
1 /// <summary> 2 /// 將DataTable轉換成Entity列表 3 /// </summary> 4 /// <param name="dt"></param> 5 /// <returns></returns> 6 public List<CoursewareInfo> ConvertDtToModelList(DataTable dt) 7 { 8 List<CoursewareInfo> list = new List<CoursewareInfo>(); 9 foreach (DataRow dr in dt.Rows) 10 { 11 list.Add(DataRowToModel(dr)); 12 } 13 return list; 14 } 15 /// <summary> 16 /// 得到一個對象實體 17 /// </summary> 18 public CoursewareInfo DataRowToModel(DataRow row) 19 { 20 CoursewareInfo model = new CoursewareInfo(); 21 if (row != null) 22 { 23 model.LocalId = row["LocalId"].ToString(); 24 model.RemoteId = row["RemoteId"].ToString(); 25 model.Name = row["Name"].ToString(); 26 } 27 return model; 28 }
獲取數據列表:
1 /// <summary> 2 /// 獲得數據列表 3 /// </summary> 4 public List<CoursewareInfo> GetCoursewares() 5 { 6 DataSet ds = GetList(string.Empty, "Courseware"); 7 //通過欄位賦值,DataSet轉實體類 8 var modelList = ConvertDtToModelList(ds.Tables[0]); 9 return modelList; 10 } 11 /// <summary> 12 /// 獲得數據列表 13 /// </summary> 14 public List<CoursewareInfo> GetCoursewares(string queryText) 15 { 16 var queryString = $"Name like '%{queryText}%'"; 17 DataSet ds = GetList(queryString, "Courseware"); 18 //通過欄位賦值,DataSet轉實體類 19 var modelList = ConvertDtToModelList(ds.Tables[0]); 20 return modelList; 21 }
來看下查詢數據的性能,還是同一數據表
首次查詢:
- 查詢2.7萬條數據,耗時660ms
- 查詢指定的1條數據,也要耗時191ms
二次查詢:
- 查詢2.7萬條數據,耗時500ms
- 查詢指定的1條數據,耗時58ms
此方案,數據查詢性能很明顯的改善。
總結:相對LINDB,使用Sql查詢方案查詢數據性能會好很多