最近感觉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