diff --git a/性能.md b/性能.md index cabbe2e..6e019d7 100644 --- a/性能.md +++ b/性能.md @@ -37,6 +37,55 @@ FreeSql以微小的性能差距输了,原因是支持了更多的类型,某 > FreeSql批量插入使用的命令:INSERT INTO Song (...) VALUES(...),VALUES(...),VALUES(...)... +## 并发测试 + +Dapper以及其他ORM,包括EFCore默认使用ado.net的连接池,FreeSql独立现实了连接池机制。假设连接池数量都为100的情况下,请看以下测试结果: + +```csharp +[HttpGet("vs_freesql")] +async public Task vs_freesql() { + var select = mysql.Select(); + var count = await select.CountAsync(); + + using (var conn = await mysql.Ado.MasterPool.GetAsync()) { + System.Threading.Thread.CurrentThread.Join(TimeSpan.FromMilliseconds(500)); + } + + var items = await select.Page(1, 20).ToListAsync(); + return new { count, items }; +} + +[HttpGet("vs_dapper")] +async public Task vs_dapper() +{ + //与freesql执行相同的SQL命令 + //将dapper的连接池大小调为101,防止与freesql共用 + var connStr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=101"; + var conn = new MySqlConnection(connStr); + conn.Open(); + var count = await conn.ExecuteScalarAsync("SELECT count(1) FROM `Song` a"); + //conn.Close(); + System.Threading.Thread.CurrentThread.Join(TimeSpan.FromMilliseconds(500)); + //conn = new SqlConnection(connStr); + //conn.Open(); + var items = await conn.QueryAsync("SELECT a.`Id`, a.`Title`, a.`Url`, a.`Create_time`, a.`Is_deleted` FROM `Song` a LIMIT 0,20"); + conn.Close(); + + return new { count, items }; +} +``` + +连接池最大为:100,101 +Song 表数据:13万 + +在中间都模拟占用连接池的连接500ms时间来阻塞后续的请求,正式环境一条命令或事务500ms是很正常的耗时。 + +ab -c 50 -n 1000 -s 6000 测试结果差不多,基本小于连接池数量都差不多。 + +-c 500 时,vs_dapper直接挂了,vs_freesql没影响。 + +测试结果证明ado.net连接池过于暴露,突然的高并发招架不住。 + ### 执行SQL返回实体列表 ```csharp @@ -87,7 +136,7 @@ public void QueryTuple() { ```csharp [Fact] -public void Query() { +public void QueryDynamic() { var sb = new StringBuilder(); var time = new Stopwatch(); @@ -110,7 +159,7 @@ public void Query() { ```csharp [Fact] -public void Query() { +public void QueryList() { var sb = new StringBuilder(); var time = new Stopwatch();