EFCore 使用DbContextPool提高EfCore查詢性能
- 2020 年 3 月 12 日
- 筆記
EFCore2.0 為DbContext引入新的註冊方式:透明地註冊了 DbContext實例池
services.AddDbContextPool<UserModelContext>(options => options.UseSqlServer(Configuration.GetConnectionString("sqlstring")));
一如既往支持lambda方式註冊連接字符串
– 默認的連接池數量為 128
– 每次使用完DbContext不會釋放對象,而是重置並回收到DBContextPool
Web程序中通過重用池中DbContext實例可提高高並發場景下的吞吐量, 這在概念上類似於ADO.NET Provider原生的連接池操作方式,具有節省DbContext實例化成本的優點, 這也是EFCore2.0 其中一個性能亮點。
驗證SQL Server會話中的有效連接數SQL:
SELECT DEC.session_id, DEC.protocol_type, DEC.auth_scheme, DES.login_name, DES.login_time FROM sys.dm_exec_sessions AS DES JOIN sys.dm_exec_connections AS DEC ON DEC.session_id = DES.session_id;
需要注意的一個坑: 查看 SqlConnention 的 實現源碼 發現連接池的默認大小限制是 100
EF Core 小坑:DbContextPool 會引起數據庫連接池連接耗盡 – dudu – 博客園 https://www.cnblogs.com/dudu/p/10398225.html
總結:
DbContextPool 的連接池數量一定要小於數據庫默認的連接池100!
知道了原因,解決起來就很簡單了,解決辦法:
1、將 DbContextPool 的 poolSize 設置為小於數據庫默認連接池的 Max_Pool_Size
services.AddDbContextPool<JobDb>(option => option.UseSqlServer(Configuration.DbConnectionStr()), poolSize: 64);
2、修改連接字符串,重新制定數據庫的連接字符串大小。
比如:
string connstr="Server=joe;Database=AdventureWorks;User ID=sa;Password=test;pooling=true;connection lifetime=0;min pool size = 10;max pool size=512";