Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam banyak kasus, cara Anda memodelkan dapat berdampak besar pada performa aplikasi Anda; sementara model yang dinormalisasi dengan benar dan "benar" biasanya merupakan titik awal yang baik, dalam aplikasi dunia nyata beberapa kompromi pragmatis dapat pergi jauh untuk mencapai performa yang baik. Karena cukup sulit untuk mengubah model Anda setelah aplikasi berjalan dalam produksi, ada baiknya mengingat performa saat membuat model awal.
Denormalisasi dan cache
Denormalisasi adalah praktik menambahkan data redundan ke skema Anda, biasanya untuk menghilangkan gabungan saat mengkueri. Misalnya, untuk model dengan Blog dan Postingan, di mana setiap Postingan memiliki Peringkat, Anda mungkin diharuskan untuk sering menunjukkan peringkat rata-rata Blog. Pendekatan sederhana untuk ini akan mengelompokkan pos menurut blog mereka dan menghitung nilai rata-rata sebagai bagian dari query; tetapi ini membutuhkan join yang mahal di antara dua tabel. Denormalisasi akan menambahkan rata-rata yang telah dihitung dari semua postingan ke kolom baru di Blog, sehingga dapat segera diakses, tanpa perlu bergabung atau menghitung.
Hal di atas dapat dilihat sebagai bentuk cache - informasi agregat dari Postingan di-cache di Blog mereka; dan seperti halnya cache apa pun, masalahnya adalah cara menjaga nilai cache tetap terbaru dengan data yang di-cache. Dalam banyak kasus, tidak masalah jika data yang di-cache mengalami keterlambatan sedikit; misalnya, dalam contoh di atas, biasanya masuk akal jika peringkat rata-rata blog tidak sepenuhnya diperbarui pada tiap saat. Jika demikian, Anda dapat menghitung ulang sesekali; jika tidak, sistem yang lebih rumit harus disiapkan untuk menjaga nilai yang di-cache diperbarui.
Berikut adalah rincian beberapa teknik untuk denormalisasi dan penembolokan di EF Core, dan merujuk ke bagian yang relevan dalam dokumentasi.
Kolom terkomputasi yang tersimpan
Jika data yang akan di-cache adalah produk kolom lain dalam tabel yang sama, maka kolom komputasi yang disimpan dapat menjadi solusi yang sempurna. Misalnya, Customer mungkin memiliki FirstName kolom dan LastName, tetapi kita mungkin perlu mencari berdasarkan nama pelanggan lengkap. Kolom komputasi yang disimpan secara otomatis dikelola oleh database - yang menghitung ulang setiap kali baris diubah - dan Anda bahkan dapat menentukan indeks di atasnya untuk mempercepat kueri.
Memperbarui kolom cache saat input berubah
Jika kolom cache Anda perlu mereferensikan input dari luar baris tabel, Anda tidak dapat menggunakan kolom komputasi. Namun, masih mungkin untuk menghitung ulang kolom setiap kali inputnya berubah; misalnya, Anda dapat menghitung ulang peringkat Blog rata-rata setiap kali Posting diubah, ditambahkan, atau dihapus. Pastikan untuk mengidentifikasi kondisi yang tepat ketika perhitungan ulang diperlukan, jika tidak, nilai cache Anda akan tidak sinkron.
Salah satu cara untuk melakukan ini, adalah dengan melakukan pembaruan sendiri, melalui API Inti EF reguler.
SaveChanges
Peristiwa atau interseptor dapat digunakan untuk secara otomatis memeriksa apakah ada Post yang diperbarui, dan untuk melakukan perhitungan ulang dengan cara itu. Perhatikan bahwa ini biasanya melibatkan perjalanan bolak-balik ke database tambahan, karena perintah tambahan harus dikirim.
Untuk aplikasi yang lebih sensitif terhadap perf, pemicu database dapat didefinisikan untuk secara otomatis melakukan perhitungan ulang dalam database. Ini menghemat perjalanan tambahan ke database, terjadi secara otomatis dalam transaksi yang sama dengan pembaruan utama, dan pengaturannya dapat lebih sederhana. EF tidak menyediakan API tertentu untuk membuat atau memelihara pemicu, tetapi sangat baik untuk membuat migrasi kosong dan menambahkan definisi pemicu melalui SQL mentah.
Tampilan materialisasi/terindeks
Tampilan materialisasi (atau terindeks) mirip dengan tampilan reguler, kecuali bahwa data mereka disimpan di disk ("terwujud"), daripada dihitung setiap kali tampilan dikueri. Pandangan tersebut secara konseptual mirip dengan kolom komputasi yang disimpan, karena mereka menyimpan cache set hasil dari perhitungan yang berpotensi memakan sumber daya besar; namun, mereka menyimpan cache seluruh set hasil kueri alih-alih satu kolom. Tampilan materialisasi dapat dikueri sama seperti tabel biasa, dan karena di-cache pada disk, kueri tersebut dijalankan dengan sangat cepat dan murah tanpa harus terus-menerus melakukan perhitungan kueri yang mahal yang menentukan tampilan.
Dukungan khusus untuk tampilan materialisasi bervariasi di seluruh database. Dalam beberapa database (misalnya PostgreSQL), tampilan materialisasi harus disegarkan secara manual agar nilainya disinkronkan dengan tabel yang mendasarnya. Ini biasanya dilakukan melalui timer - dalam kasus di mana beberapa jeda data dapat diterima - atau melalui pemicu atau panggilan prosedur tersimpan dalam kondisi tertentu. Indeks Tampilan pada SQL Server, sebaliknya, secara otomatis diperbarui ketika tabel dasarnya dimodifikasi; ini memastikan bahwa tampilan selalu menunjukkan data terbaru, dengan konsekuensi pembaruan yang lebih lambat. Selain itu, Tampilan Indeks SQL Server memiliki berbagai batasan pada apa yang mereka dukung; lihat dokumentasi untuk informasi lebih lanjut.
EF saat ini tidak menyediakan API khusus untuk membuat atau memelihara tampilan, baik yang materialized/diindeks maupun lainnya; tetapi tidak masalah untuk membuat migrasi kosong dan menambahkan definisi tampilan dengan SQL mentah.
Pemetaan pewarisan
Disarankan untuk membaca halaman khusus tentang warisan sebelum melanjutkan dengan bagian ini.
EF Core saat ini mendukung tiga teknik untuk memetakan model warisan ke database relasional:
- Tabel per hierarki (TPH), di mana seluruh hierarki .NET kelas dipetakan ke tabel database tunggal.
- Tabel per jenis (TPT), di mana setiap jenis dalam hierarki .NET dipetakan ke tabel lain dalam database.
- Table-per-concrete-type (TPC), di mana setiap jenis beton dalam hierarki .NET dipetakan ke tabel yang berbeda dalam database, di mana setiap tabel berisi kolom untuk semua properti jenis yang sesuai.
Pilihan teknik pemetaan warisan dapat memiliki dampak yang cukup besar pada performa aplikasi - disarankan untuk mengukur dengan hati-hati sebelum berkomitmen pada pilihan.
Secara intuitif, TPT mungkin tampak seperti teknik "lebih bersih"; tabel terpisah untuk setiap jenis .NET membuat skema database terlihat mirip dengan hierarki jenis .NET. Selain itu, karena TPH harus mewakili seluruh hierarki dalam satu tabel, baris memiliki semua kolom tanpa memandang jenis yang sebenarnya terdapat dalam baris, dan kolom yang tidak terkait selalu kosong dan tidak terpakai. Selain tampak sebagai teknik pemetaan yang "tidak bersih", banyak yang percaya bahwa kolom kosong ini mengambil ruang yang cukup besar dalam database dan mungkin menyakiti performa juga.
Petunjuk / Saran
Jika sistem database Anda mendukungnya (e.g. SQL Server), maka pertimbangkan untuk menggunakan "kolom jarang" untuk kolom TPH yang jarang diisi.
Namun, pengukuran menunjukkan bahwa TPT dalam banyak kasus teknik pemetaan inferior dari sudut performa; di mana semua data dalam TPH berasal dari satu tabel, kueri TPT harus bergabung bersama beberapa tabel, dan gabungan adalah salah satu sumber utama masalah performa dalam database relasional. Basis data juga umumnya cenderung berurusan dengan baik dengan kolom kosong, dan fitur seperti kolom sparse SQL Server dapat mengurangi overhead ini lebih jauh.
TPC memiliki karakteristik performa yang sama dengan TPH, tetapi sedikit lebih lambat saat memilih entitas dari semua jenis karena ini melibatkan beberapa tabel. Namun, TPC benar-benar unggul saat mengkueri entitas dari jenis daun tunggal - kueri hanya menggunakan satu tabel dan tidak memerlukan pemfilteran.
Untuk contoh konkret, lihat tolok ukur ini yang menyiapkan model sederhana dengan hierarki 7 jenis; 5000 baris dimasukkan untuk setiap jenis - berjumlah total 35000 baris - dan tolok ukur memuat semua baris dari database:
| Metode | Rata-rata | Kesalahan | StdDev | Gen 0 | Gen 1 | Dialokasikan |
|---|---|---|---|---|---|---|
| TPH | 149,0 ms | 3,38 milidetik | 9,80 ms | 4000.0000 | 1000.0000 | 40 MB |
| TPT | 312,9 ms | 6,17 mdtk | 10.81 ms | 9000.0000 | 3000.0000 | 75 MB |
| TPC | 158,2 ms | 3,24 ms | 8,88 ms | 5000.0000 | 2000.0000 | 46 MB |
Seperti yang dapat dilihat, TPH dan TPC jauh lebih efisien daripada TPT untuk skenario ini. Perhatikan bahwa hasil aktual selalu bergantung pada kueri tertentu yang dijalankan dan jumlah tabel dalam hierarki, sehingga kueri lain mungkin menunjukkan kesenjangan performa yang berbeda; Anda dianjurkan untuk menggunakan kode tolok ukur ini sebagai templat untuk menguji kueri lain.