# EF Core Performance: Common Problems and Practical Fixes
Nếu SQL chạy nhanh trong SSMS nhưng endpoint vẫn chậm, vấn đề có thể nằm ở EF Core, materialization, tracking, serialization hoặc payload chứ không chỉ ở database.
## AsNoTracking
Nếu chỉ đọc:
“`csharp
var users = await dbContext.Users
.AsNoTracking()
.ToListAsync();
“`
Lợi ích:
– giảm Change Tracker overhead
– giảm memory usage
– phù hợp read-only query
## Projection
Không nên load toàn entity nếu chỉ cần vài fields.
“`csharp
var users = await dbContext.Users
.AsNoTracking()
.Select(x => new UserDto
{
Id = x.Id,
Name = x.Name
})
.ToListAsync();
“`
## Include
“`csharp
.Include(x => x.Orders)
“`
hữu ích nhưng có thể tạo:
– query lớn
– duplicated data
– cartesian explosion
Không nên Include toàn bộ object graph theo thói quen.
## Split Query
Trong một số graph lớn:
“`csharp
.AsSplitQuery()
“`
có thể giúp tránh cartesian explosion.
Trade-off là nhiều round trips hơn.
## IQueryable vs IEnumerable
Không tốt:
“`csharp
var users = dbContext.Users
.ToList()
.Where(x => x.IsActive);
“`
Dữ liệu đã được load về memory trước khi filter.
Tốt hơn:
“`csharp
var users = await dbContext.Users
.Where(x => x.IsActive)
.ToListAsync();
“`
## ExecuteUpdateAsync
“`csharp
await dbContext.Users
.Where(x => x.IsInactive)
.ExecuteUpdateAsync(setters =>
setters.SetProperty(x => x.Status, “Disabled”));
“`
Có thể update trực tiếp mà không cần load entities về memory.
## Tại sao EF Core có thể chậm?
– Tracking overhead
– Excessive Includes
– N+1 queries
– Loading too many columns
– Premature materialization
– Poor indexes
– Inefficient SQL translation
– Large serialization payload
## Interview questions
### When should you use AsNoTracking?
> For read-only queries where I don’t need EF Core to detect and persist changes to the returned entities.
### Why can EF Core be slow even if SQL is simple?
> Because query performance also includes tracking, object materialization, navigation loading, serialization, and the amount of data moved between the database and application.
## Key takeaways
Tối ưu EF Core không phải chỉ thêm `AsNoTracking()`. Cần nhìn toàn pipeline:
“`text
LINQ
↓
Generated SQL
↓
Database execution
↓
Materialization
↓
Tracking
↓
Serialization
“`
**Next:** Part 8 — Optimistic vs Pessimistic Concurrency