Bagikan melalui


Pengantar Performa

Performa database adalah topik yang luas dan kompleks, mencakup seluruh tumpukan komponen: database, jaringan, driver database, dan lapisan akses data seperti EF Core. Sementara lapisan tingkat tinggi dan O/RM seperti EF Core sangat menyederhanakan pengembangan aplikasi dan meningkatkan keberlanjutan, mereka terkadang dapat buram, menyembunyikan detail internal kritis performa seperti SQL yang dijalankan. Bagian ini mencoba memberikan gambaran umum tentang cara mencapai performa yang baik dengan EF Core, dan cara menghindari jebakan umum yang dapat menurunkan performa aplikasi.

Mengidentifikasi hambatan dan terus mengukur

Seperti biasa dengan performa, penting untuk tidak terburu-buru ke pengoptimalan tanpa data yang menunjukkan masalah; seperti yang pernah dikatakan oleh Donald Knuth yang hebat, "Pengoptimalan dini adalah akar dari semua kejahatan". Bagian diagnosis performa membahas berbagai cara untuk memahami di mana aplikasi Anda menghabiskan waktu dalam logika database, dan cara menentukan area bermasalah tertentu. Setelah kueri lambat diidentifikasi, solusi dapat dipertimbangkan: apakah database Anda kehilangan indeks? Haruskah Anda mencoba pola kueri lainnya?

Selalu lakukan tolok ukur kode Anda dan kemungkinan alternatif Anda sendiri - bagian diagnosis kinerja berisi benchmark sampel dengan BenchmarkDotNet, yang dapat Anda gunakan sebagai templat untuk benchmark Anda sendiri. Jangan berasumsi bahwa tolok ukur publik umum berlaku apa adanya untuk kasus penggunaan spesifik Anda; berbagai faktor seperti latensi database, kompleksitas kueri, dan jumlah data aktual dalam tabel Anda dapat memiliki efek mendalam tentang solusi mana yang terbaik. Misalnya, banyak tolok ukur publik dilakukan dalam kondisi jaringan yang ideal, di mana latensi ke database hampir nol, dan dengan kueri yang sangat ringan yang hampir tidak memerlukan pemrosesan (atau I/O disk) di sisi database. Meskipun ini berharga untuk membandingkan overhead runtime dari lapisan akses data yang berbeda, perbedaan yang mereka ungkapkan biasanya terbukti dapat diabaikan dalam aplikasi dunia nyata, di mana database melakukan pekerjaan dan latensi aktual ke database adalah faktor performa yang signifikan.

Aspek performa akses data

Performa akses data secara keseluruhan dapat dipecah menjadi kategori luas berikut:

  • Performa database murni. Dengan database relasional, EF menerjemahkan kueri LINQ aplikasi ke dalam pernyataan SQL yang dijalankan oleh database; pernyataan SQL ini sendiri dapat berjalan lebih atau kurang efisien. Indeks yang tepat di tempat yang tepat dapat membuat dunia perbedaan dalam performa SQL, atau menulis ulang kueri LINQ Anda dapat membuat EF menghasilkan kueri SQL yang lebih baik.
  • Kecepatan transfer data jaringan. Seperti halnya sistem jaringan lainnya, penting untuk membatasi jumlah data yang bolak-balik melalui kabel. Ini mencakup memastikan bahwa Anda hanya mengirim dan memuat data yang benar-benar Anda perlukan, tetapi juga menghindari apa yang disebut efek "ledakan kartesius" saat memuat entitas terkait.
  • Perjalanan bolak-balik jaringan. Di luar jumlah data yang bolak-balik, perjalanan bolak-balik jaringan, karena waktu yang dibutuhkan untuk mengeksekusi kueri dalam database dapat dikerdilkan oleh paket waktu yang berjalan bolak-balik antara aplikasi Anda dan database Anda. Overhead bolak-balik sangat tergantung pada lingkungan Anda; semakin jauh server database Anda, semakin tinggi latensi dan semakin mahal setiap perjalanan bolak-balik. Dengan munculnya cloud, aplikasi semakin menjauh dari database, dan aplikasi "cerewet" yang melakukan terlalu banyak perjalanan bolak-balik mengalami penurunan kinerja. Oleh karena itu, penting untuk memahami dengan tepat kapan aplikasi Anda menghubungi database, berapa banyak perjalanan pulang pergi yang dilakukan, dan apakah jumlah tersebut dapat diminimalkan.
  • Overhead runtime EF. Terakhir, EF sendiri menambahkan beberapa overhead runtime ke operasi database: EF perlu mengompilasi kueri Anda dari LINQ ke SQL (walaupun itu biasanya harus dilakukan hanya sekali), pelacakan perubahan menambahkan beberapa overhead (tetapi dapat dinonaktifkan), dll. Dalam praktiknya, overhead EF untuk aplikasi dunia nyata cenderung diabaikan dalam banyak kasus, karena waktu eksekusi kueri dalam database dan latensi jaringan mendominasi total waktu; tetapi penting untuk memahami apa pilihan Anda dan bagaimana menghindari beberapa perangkap.

Ketahui apa yang terjadi dalam operasi internal

EF memungkinkan pengembang untuk berkonsentrasi pada logika bisnis dengan menghasilkan SQL, mewujudkan hasil, dan melakukan tugas lain. Seperti lapisan atau abstraksi apa pun, itu juga cenderung menyembunyikan apa yang terjadi di bawah tenda, seperti kueri SQL aktual yang dijalankan. Performa belum tentu merupakan aspek penting dari setiap aplikasi di luar sana, tetapi dalam aplikasi di mana itu, sangat penting bahwa pengembang memahami apa yang dilakukan EF untuk mereka: memeriksa kueri SQL keluar, ikuti perjalanan bolak-balik untuk memastikan masalah N+1 tidak terjadi, dll.

Cache di luar database

Terakhir, cara paling efisien untuk berinteraksi dengan database adalah dengan tidak berinteraksi sama sekali. Dengan kata lain, jika akses database muncul sebagai hambatan performa dalam aplikasi Anda, mungkin ada baiknya untuk menyimpan hasil tertentu di luar database, untuk meminimalkan permintaan. Meskipun penembolokan menambah kompleksitas, ini adalah bagian yang sangat penting dari setiap aplikasi yang dapat diskalakan: sementara tingkat aplikasi dapat dengan mudah diskalakan dengan menambahkan server tambahan untuk menangani peningkatan beban, penskalaan tingkat database biasanya jauh lebih rumit.