Kueri Terkompilasi & Performa
Tingkatkan performa kueri menggunakan EF.CompileQuery, AsNoTracking, dan proyeksi dengan Select.
Kueri Terkompilasi & Performa adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.
Kompilasi Kueri EF Core
Setiap kali EF Core menjalankan kueri LINQ, EF Core harus mengurai pohon ekspresi, menerjemahkannya ke SQL, dan memvalidasinya. Untuk jalur kritis yang sering dijalankan, beban tambahan ini terakumulasi. EF Core menyediakan beberapa alat untuk meminimalkannya.
AsNoTracking untuk Kueri Hanya-Baca
AsNoTracking() melewati pendaftaran pada pelacak perubahan. Untuk kueri hanya-baca (respons API, laporan), ini merupakan peningkatan mudah terbesar — biasanya 2–5 kali lebih cepat dan menggunakan lebih sedikit memori.
// With tracking (default) — for entities you'll modify
var tracked = await _db.Products.FirstOrDefaultAsync(p => p.Id == 1);
// Without tracking — for read-only
var dto = await _db.Products
.AsNoTracking()
.Where(p => p.IsActive)
.Select(p => new ProductDto { Id = p.Id, Name = p.Name })
.ToListAsync();Kueri Terkompilasi
EF.CompileAsyncQuery melakukan prakompilasi kueri LINQ menjadi delegasi. Penerjemahan dilakukan sekali saat aplikasi dimulai; pemanggilan berikutnya sepenuhnya melewati langkah kompilasi.
// Define once, reuse many times
private static readonly Func<AppDbContext, int, Task<Product?>> GetProductById =
EF.CompileAsyncQuery(
(AppDbContext db, int id) =>
db.Products.AsNoTracking().FirstOrDefault(p => p.Id == id));
// Usage
var product = await GetProductById(_db, 42);Proyeksi dengan Select untuk Kinerja
Selalu lakukan proyeksi hanya ke bidang yang benar-benar diperlukan. Memilih DTO, bukan entitas lengkap, mengurangi kolom yang diambil, muatan jaringan, dan tekanan pada pengumpul sampah.
// Load entire entity (over-fetch)
var all = await _db.Products.ToListAsync();
// Projection: only fetch needed columns
var names = await _db.Products
.AsNoTracking()
.Select(p => new { p.Id, p.Name, p.Price })
.ToListAsync();
// SQL: SELECT Id, Name, Price FROM ProductsPetunjuk Indeks dan Optimasi Kueri Mentah
EF Core menggunakan indeks basis data yang Anda konfigurasi dengan HasIndex(). Indeks gabungan, indeks terfilter, dan kolom yang disertakan semuanya memengaruhi kinerja rencana kueri.
// Configure compound index in OnModelCreating
modelBuilder.Entity<Order>()
.HasIndex(o => new { o.CustomerId, o.Status })
.HasFilter("[Status] = 0") // filtered index
.IncludeProperties(o => o.PlacedAt);
// The query below will use this index efficiently
var pending = await _db.Orders
.AsNoTracking()
.Where(o => o.CustomerId == 5 && o.Status == OrderStatus.Pending)
.ToListAsync();Pembagian Halaman dengan Skip dan Take
Selalu bagi halaman untuk kumpulan hasil yang besar. Skip dan Take diterjemahkan menjadi SQL OFFSET/FETCH sehingga ribuan baris tidak perlu dimuat ke memori.
int page = 2, pageSize = 25;
var products = await _db.Products
.AsNoTracking()
.Where(p => p.IsActive)
.OrderBy(p => p.Name)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
// SQL: ... ORDER BY Name OFFSET 25 ROWS FETCH NEXT 25 ROWS ONLYMenghitung Secara Efisien
Gunakan CountAsync() atau AnyAsync() alih-alih memuat rekaman hanya untuk menghitungnya. AnyAsync() bahkan lebih cepat daripada COUNT jika Anda hanya perlu memeriksa keberadaan data.
// Total count for pagination
int totalCount = await _db.Products
.Where(p => p.IsActive)
.CountAsync();
// Existence check — faster than Count > 0
bool hasExpensive = await _db.Products
.AnyAsync(p => p.Price > 1000m);
// SQL: IF EXISTS (SELECT 1 FROM ...) SELECT 1Penyisipan Massal dengan AddRange
Gunakan AddRange untuk menambahkan beberapa entitas sekaligus. EF Core mengelompokkan INSERT menjadi lebih sedikit perjalanan bolak-balik, yang dikendalikan oleh MaxBatchSize pada penyedia basis data.
var newProducts = Enumerable.Range(1, 1000)
.Select(i => new Product { Name = $"Product {i}", Price = i * 1.5m })
.ToList();
_db.Products.AddRange(newProducts);
await _db.SaveChangesAsync();
// Batched: typically 100-1000 rows per round-tripEF.Functions untuk Fungsi Basis Data
EF.Functions menyediakan fungsi khusus basis data (LIKE, bagian tanggal, pencarian teks lengkap) yang diterjemahkan EF Core ke SQL, bukan dievaluasi di memori.
// LIKE pattern search (SQL-side)
var results = await _db.Products
.Where(p => EF.Functions.Like(p.Name, "%keyboard%"))
.AsNoTracking()
.ToListAsync();
// Date difference (SQL-side)
var recentOrders = await _db.Orders
.Where(o => EF.Functions.DateDiffDay(o.PlacedAt, DateTime.UtcNow) <= 7)
.ToListAsync();Mendiagnosis Kueri yang Lambat
Aktifkan pencatatan kueri EF Core untuk melihat SQL yang dihasilkan. Gunakan EnableSensitiveDataLogging() dalam pengembangan untuk melihat nilai parameter.
builder.Services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlServer(connStr)
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging() // dev only!
.EnableDetailedErrors()); // dev only!Dunia Nyata: Titik Akhir Daftar yang Dioptimalkan
Titik akhir daftar yang siap produksi menggabungkan AsNoTracking, proyeksi, indeks, dan pembagian halaman untuk kinerja maksimum.
app.MapGet("/products", async (
AppDbContext db,
string? search,
int page = 1, int size = 20) =>
{
var query = db.Products
.AsNoTracking()
.Where(p => p.IsActive);
if (!string.IsNullOrEmpty(search))
query = query.Where(p => EF.Functions.Like(p.Name, $"%{search}%"));
var total = await query.CountAsync();
var items = await query
.OrderBy(p => p.Name)
.Skip((page - 1) * size).Take(size)
.Select(p => new { p.Id, p.Name, p.Price })
.ToListAsync();
return Results.Ok(new { total, items });
});Pemeriksaan Singkat
Apa manfaat utama EF.CompileAsyncQuery dibandingkan kueri LINQ biasa?
Ringkasan: Kueri Terkompilasi & Kinerja
Hal-hal penting:
AsNoTracking(): lewati pelacak perubahan untuk operasi hanya-baca — peningkatan mudah yang paling cepatEF.CompileAsyncQuery: lakukan prakompilasi atas kueri yang sering dijalankan menjadi delegasi- Proyeksi dengan
Select: hanya mengambil kolom yang diperlukan - Indeks yang tepat (
HasIndex) secara drastis meningkatkan rencana kueri - Gunakan pembagian halaman dengan
Skip/Take; gunakanAnyAsyncuntuk memeriksa keberadaan data - Aktifkan pencatatan kueri dalam pengembangan untuk menemukan SQL yang lambat atau tidak terduga
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Kueri Terkompilasi & Performa” gratis?
Ya — teks lengkap “Kueri Terkompilasi & Performa” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Kueri Terkompilasi & Performa”?
Tingkatkan performa kueri menggunakan EF.CompileQuery, AsNoTracking, dan proyeksi dengan Select. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C# Academy?
Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Kueri Terkompilasi & Performa” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?
Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pemuatan Eager, Lazy & Eksplisit
- SQL Mentah, Prosedur Tersimpan & Interpolasi
- Kueri Terkompilasi & Performa
- Filter Kueri Global & Entitas Owned