優化數據訪問和I/O操作
數據交互以及遠程服務通常是程序中最慢的部分,高效的讀寫數據對性能尤其重要。
建議操作:
- 異步方式調用所有數據訪問API。
- 不要獲取非必須的數據,近返回當前Http 請求需要的數據。
- 在數據過期是可接受的情況下,可以考慮緩存頻繁訪問的數據(從數據庫中讀取或遠程服務返回的數據)。根據實際應用場景,可以使用內存緩存(MemoryCache)或分布式緩存(DistributedCache)。
- 減少網絡往返。也就是說盡量一次請求返回所需數據,避免多次請求。
- 使用Entity Framework Core時,如果只是讀取數據,可以用非跟蹤查詢模式(no-tracking queries),這樣可以提升查詢性能。
- 使用Linq 查詢時,可使用
Where
,.Select
,.Sum
等方法過濾或聚合查詢,從而在數據庫中進行過濾。 - 一定要注意EF Core在客戶端的某些查詢解析,可能無效。(某些自定義的匹配條件)詳情查看: Client evaluation performance issues.
- 不要在集合上使用映射查詢,會導致N+1查詢問題。詳情查看:Optimization of correlated subqueries.
在高性能EF中提到下面兩個提高性能的方法:
使用 DbContext 池
services.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));
使用已編譯的查詢(compiled query)
// Create an explicitly compiled query private static Func<CustomerContext, int, Customer> _customerById = EF.CompileQuery((CustomerContext db, int id) => db.Customers .Include(c => c.Address) .Single(c => c.Id == id)); // Use the compiled query by invoking it using (var db = new CustomerContext()) { var customer = _customerById(db, 147); }
以上兩種方式要在重復評估,性能測試之后再使用,因為已編譯的查詢在某些情況下可能並不會帶來性能提升。
查詢性能問題可以通過Application Insights或其他分析工具,分析數據訪問耗時來發現。大多數數據庫會提供頻繁查詢的統計信息,可以幫助開發人員進行分析。