最近感覺freesql很火,很多github 項目使用這個orm框架。
關於這幾個框架的執行測評如下。
插入性能:
FreeSql Insert 1條數據,循環100次,耗時41ms
SqlSugar Insert 1條數據,循環100次,耗時33ms
EFCore Insert 1條數據,循環100次,耗時113ms
FreeSql Insert 10條數據,循環100次,耗時49ms
SqlSugar Insert 10條數據,循環100次,耗時175ms
EFCore Insert 10條數據,循環100次,耗時264ms
FreeSql Insert 1000條數據,循環1次,耗時75ms
SqlSugar Insert 1000條數據,循環1次,耗時73ms
EFCore Insert 1000條數據,循環1次,耗時120ms
FreeSql Insert 10000條數據,循環1次,耗時709ms
SqlSugar Insert 10000條數據,循環1次,耗時692ms
EFCore Insert 10000條數據,循環1次,耗時867ms
FreeSql Insert 50000條數據,循環1次,耗時3493ms
SqlSugar Insert 50000條數據,循環1次,耗時3520ms
EFCore Insert 50000條數據,循環1次,耗時4424ms
FreeSql Insert 100000條數據,循環1次,耗時7053ms
SqlSugar Insert 100000條數據,循環1次,耗時7062ms
EFCore Insert 100000條數據,循環1次,耗時8867ms
查詢性能:
FreeSql Select 1條數據,循環100次,耗時38ms
SqlSugar Select 1條數據,循環100次,耗時71ms
EFCore Select 1條數據,循環100次,耗時208ms
Dapper Select 1條數據,循環100次,耗時55ms
FreeSql Select 10條數據,循環100次,耗時11ms
SqlSugar Select 10條數據,循環100次,耗時31ms
EFCore Select 10條數據,循環100次,耗時34ms
Dapper Select 10條數據,循環100次,耗時14ms
FreeSql Select 1000條數據,循環1次,耗時1ms
SqlSugar Select 1000條數據,循環1次,耗時2ms
EFCore Select 1000條數據,循環1次,耗時4ms
Dapper Select 1000條數據,循環1次,耗時2ms
FreeSql Select 10000條數據,循環1次,耗時9ms
SqlSugar Select 10000條數據,循環1次,耗時11ms
EFCore Select 10000條數據,循環1次,耗時15ms
Dapper Select 10000條數據,循環1次,耗時12ms
FreeSql Select 50000條數據,循環1次,耗時46ms
SqlSugar Select 50000條數據,循環1次,耗時64ms
EFCore Select 50000條數據,循環1次,耗時83ms
Dapper Select 50000條數據,循環1次,耗時56ms
FreeSql Select 100000條數據,循環1次,耗時87ms
SqlSugar Select 100000條數據,循環1次,耗時106ms
EFCore Select 100000條數據,循環1次,耗時197ms
Dapper Select 100000條數據,循環1次,耗時194ms
更新性能:
SqlSugar Update 1條數據,循環100次,耗時51ms
FreeSql Update 1條數據,循環100次,耗時34ms
EFCore Update 1條數據,循環100次,耗時67ms
SqlSugar Update 10條數據,循環100次,耗時119ms
FreeSql Update 10條數據,循環100次,耗時83ms
EFCore Update 10條數據,循環100次,耗時112ms
SqlSugar Update 1000條數據,循環1次,耗時96ms
FreeSql Update 1000條數據,循環1次,耗時286ms
EFCore Update 1000條數據,循環1次,耗時120ms
SqlSugar Update 10000條數據,循環1次,耗時988ms
FreeSql Update 10000條數據,循環1次,耗時2695ms
EFCore Update 10000條數據,循環1次,耗時736ms
結論
插入性能表現上FreeSql 和SqlSugar 表現差不多。
查詢性能表現上FreeSql 比 SqlSugar 稍好一些。
更新性能FreeSql 在大量數據更新的情況下,表現非常差勁,反倒是EFCore出乎我的意料了。
通過sqlserver profile追蹤了這幾個orm的數據更新方式。
--sqlsuger EXEC sp_executesql N'UPDATE [sugar_song] SET[create_time]=@create_time,[is_deleted]=@is_deleted,[title]=@title,[url]=@url WHERE [id]=@id', N'@id int,@create_time datetime,@is_deleted bit,@title nvarchar(4000),@url nvarchar(4000)', @id = 162112,@create_time = '2020-12-29 10:32:31.413',@is_deleted = 1,@title = N'Insert_0',@url = N'Url_0_U_U' --efcore exec sp_executesql N'SET NOCOUNT ON;UPDATE [efcore_song] SET [create_time] = @p0, [is_deleted] = @p1, [title] = @p2, [url] = @p3 WHERE [id] = @p4; SELECT @@ROWCOUNT;', N'@p4 int,@p0 datetime2(7),@p1 bit,@p2 nvarchar(4000),@p3 nvarchar(4000)', @p4=1,@p0='2020-12-29 10:32:32.0300000',@p1=1,@p2=N'Insert_0',@p3=N'Url_0_U_U' --freesql UPDATE [freesql_song] SET [create_time] = '2020-12-29 10:32:31.390', [is_deleted] = 1, [title] = N'Insert_0', [url] = N'Url_0_U_U' WHERE ([id] = 162112)
SqlSugar和EFCore都使用了 sp_executesql,而FreeSql就是一個簡單的UPDATE 執行語句。
sp_executesql的優勢:它提供了輸入輸出接口,可以將輸入輸出變量直接傳遞到SQL語句中,能夠重用執行計划,大大提高了執行的性能。
同時在EFCore中還使用了
SET NOCOUNT ON;SELECT @@ROWCOUNT;
當 SET NOCOUNT 為 ON 時,不返回計數(表示受 Transact-SQL 語句影響的行數)。
當 SET NOCOUNT 為 OFF 時,返回計數。
即使當 SET NOCOUNT 為 ON 時,也更新 @@ROWCOUNT 函數。
當SET NOCOUNT ON時候,將不向客戶端發送存儲過程每個語句的DONE_IN_proc消息,如果存儲過程中包含一些並不返回實際數據的語句,網絡通信流量便會大量減少,可以顯著提高應用程序性能;
SET NOCOUNT 指定的設置時在執行或運行時候生效,分析時候不生效。
執行結果如下:
SET NOCOUNT ON; SELECT TOP 5 UserName FROM T_E_BASE_PROCESS GO
SET NOCOUNT OFF; SELECT TOP 5 UserName FROM T_E_BASE_PROCESS GO
SET NOCOUNT ON; SELECT TOP 3 UserName FROM T_E_BASE_PROCESS GO SELECT @@ROWCOUNT
還有一個語句sp_reset_connection的出現。
sp_reset_connection存儲過程用於重置連接。
sp_reset_connection重置連接的以下方面:
- 它重置所有錯誤狀態和數字(如@@ error)
- 它停止所有EC(執行上下文),它們是執行並行查詢的父EC的子線程
- 它將等待任何未完成的I / O操作
- 它將通過連接釋放服務器上的任何保留緩沖區
- 它將解鎖連接使用的所有緩沖區資源
- 它將釋放連接所擁有的所有內存
- 它將清除由連接創建的任何工作或臨時表
- 它將殺死連接所擁有的所有全局游標
- 它將關閉所有打開的打開的SQL-XML句柄
- 它將刪除任何打開的SQL-XML相關工作表
- 它將關閉所有系統表
- 它將關閉所有用戶表
- 它將刪除所有臨時對象
- 它將中止未平倉交易
- 在入伍時它將從分布式交易中出現缺陷
- 它將減少當前數據庫中用戶的引用計數; 哪個發布共享數據庫鎖
- 它將釋放獲得的鎖
- 它將釋放可能已獲得的任何句柄
- 它會將所有SET選項重置為默認值
- 它將重置@@ rowcount值
- 它將重置@@ identity值
- 它將使用dbcc traceon()重置任何會話級跟蹤選項
sp_reset_connection不會重置:
- 安全上下文,這就是連接池根據確切的連接字符串匹配連接的原因
- 如果使用sp_setapprole輸入了應用程序角色,則無法還原應用程序角色
- 事務隔離級別
代碼地址:https://github.com/dotnetcore/FreeSql/tree/master/Examples/orm_vs
參考:https://cloud.tencent.com/developer/ask/202098