# 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