Dalam jawaban ini saya fokus pada pengamatan asli:kueri yang dihasilkan oleh EF lambat, tetapi ketika kueri yang sama dijalankan di SSMS, itu cepat.
Satu penjelasan yang mungkin dari perilaku ini adalah Mengendus parameter .
Jadi, EF menghasilkan kueri yang memiliki beberapa parameter. Saat pertama kali Anda menjalankan kueri ini, server membuat rencana eksekusi untuk kueri ini menggunakan nilai parameter yang berlaku saat pertama kali dijalankan. Rencana itu biasanya cukup bagus. Namun, nanti Anda menjalankan kueri EF yang sama menggunakan nilai parameter lainnya. Ada kemungkinan bahwa untuk nilai parameter baru rencana yang dihasilkan sebelumnya tidak optimal dan kueri menjadi lambat. Server tetap menggunakan paket sebelumnya, karena querynya masih sama, hanya nilai parameternya saja yang berbeda.
Jika saat ini Anda mengambil teks kueri dan mencoba menjalankannya langsung di SSMS, server akan membuat rencana eksekusi baru, karena secara teknis kueri tersebut tidak sama dengan yang dikeluarkan oleh aplikasi EF. Bahkan satu perbedaan karakter sudah cukup, setiap perubahan dalam pengaturan sesi juga cukup bagi server untuk memperlakukan kueri sebagai yang baru. Akibatnya server memiliki dua rencana untuk kueri yang tampaknya sama dalam cache-nya. Paket "lambat" pertama lambat untuk nilai parameter baru, karena awalnya dibuat untuk nilai parameter yang berbeda. Paket "cepat" kedua dibuat untuk nilai parameter saat ini, jadi cepat.
Artikel Lambat dalam Aplikasi, Cepat di SSMS oleh Erland Sommarskog menjelaskan hal ini dan bidang terkait lainnya dengan lebih detail.
Ada beberapa cara untuk membuang paket yang di-cache dan memaksa server untuk membuatnya kembali. Mengubah tabel atau mengubah indeks tabel harus dilakukan - itu harus membuang semua rencana yang terkait dengan tabel ini, baik "lambat" dan "cepat". Kemudian Anda menjalankan kueri dalam aplikasi EF dengan nilai parameter baru dan mendapatkan paket "cepat" baru. Anda menjalankan kueri di SSMS dan mendapatkan paket "cepat" kedua dengan nilai parameter baru. Server masih menghasilkan dua paket, tetapi kedua paket sekarang cepat.
Varian lain menambahkan OPTION(RECOMPILE)
ke kueri. Dengan opsi ini, server tidak akan menyimpan paket yang dihasilkan dalam cache-nya. Jadi, setiap kali kueri dijalankan, server akan menggunakan nilai parameter aktual untuk menghasilkan rencana yang (menurutnya) akan optimal untuk nilai parameter yang diberikan. Kelemahannya adalah biaya tambahan dari pembuatan paket.
Ingat, server masih dapat memilih paket "buruk" dengan opsi ini karena statistik yang sudah ketinggalan zaman, misalnya. Tapi, setidaknya, parameter sniffing tidak akan menjadi masalah.
Mereka yang bertanya-tanya bagaimana cara menambahkan OPTION (RECOMPILE)
petunjuk untuk kueri yang dihasilkan oleh EF lihat jawaban ini:
https://stackoverflow.com/a/26762756/4116017