بهینهسازی Query در EF Core چطور انجام میشود؟
تکنیکهای عمیقتر برای تحلیل و بهبود SQL واقعی تولیدشده توسط EF Core — از بررسی SQL نهایی تا Split Query برای جلوگیری از انفجار داده.
چرا مهم است؟
EF Core همیشه بهترین SQL ممکن را تولید نمیکند؛ دانستن نحوه بررسی و اصلاح SQL واقعی تولیدشده، تفاوت بین یک Endpoint سریع و یک Endpoint که زیر بار واقعی از پا میافتد را میسازد.
دیدن SQL واقعی تولیدشده
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString).LogTo(Console.WriteLine, LogLevel.Information));
این کار SQL نهایی هر Query را در Log چاپ میکند — اولین قدم هر بهینهسازی واقعی.
Cartesian Explosion و Split Query
وقتی چند Include روی چند Collection همزمان اجرا میشود، EF Core ممکن است یک JOIN بزرگ بسازد که تعداد ردیفهای نتیجه بهشکل ضربی (Cartesian) منفجر شود:
// ممکن است نتیجهای بسیار بزرگتر از انتظار برگرداند
var orders = await context.Orders
.Include(o => o.Items)
.Include(o => o.Payments)
.ToListAsync();
// راهحل: چند Query جدا بهجای یک JOIN بزرگ
var orders = await context.Orders
.Include(o => o.Items)
.Include(o => o.Payments)
.AsSplitQuery()
.ToListAsync();
نکات دیگر
- از
Any()/Count()بهجای.Count() > 0یا واکشی کل لیست برای بررسی وجود داده استفاده کنید. - Indexهای دیتابیس باید متناظر با ستونهایی باشند که در
Where/Joinاستفاده میشوند — EF Core خودش Index نمیسازد، فقط SQL تولید میکند.
اشتباه رایج
❌ حدسزدن دلیل کندی یک Query بدون نگاهکردن به SQL واقعی یا Execution Plan آن — همیشه اول با LogTo یا Execution Plan دیتابیس، مشکل واقعی را پیدا کنید، بعد راهحل انتخاب کنید.
منبع و مطالعه بیشتر
خلاصه
بهینهسازی Query در EF Core با دیدن SQL واقعی (LogTo) شروع میشود؛ AsSplitQuery از انفجار داده هنگام چند Include جلوگیری میکند. هرگز بدون بررسی SQL واقعی یا Execution Plan حدس نزنید. مرجع کامل: Single vs. Split Queries، Microsoft Learn.
