Misalkan saya punya 2 tabel, Produk dan Kategori Produk. Kedua tabel memiliki hubungan di CategoryId. Dan ini adalah kueri.
SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;
Ketika saya membuat rencana eksekusi, tabel ProductCategories melakukan pencarian indeks kluster, yang sesuai harapan. Tetapi untuk tabel Produk, ia melakukan scan indeks cluster, yang membuat saya ragu. Mengapa FK tidak membantu meningkatkan kinerja kueri?
Jadi saya harus membuat indeks di Products.CategoryId. Ketika saya membuat rencana eksekusi lagi, kedua tabel melakukan pencarian indeks. Dan diperkirakan biaya subtree berkurang banyak.
Pertanyaan saya adalah:
Selain FK membantu dalam kendala hubungan, apakah ada manfaat lain? Apakah ini meningkatkan kinerja permintaan?
Haruskah saya membuat indeks pada semua kolom FK (disukai Products.CategoryId) di semua tabel?
sumber
Kunci Asing dapat meningkatkan (dan melukai) kinerja
Seperti yang dinyatakan di sini: Kunci asing meningkatkan kinerja
Anda harus selalu membuat indeks pada kolom FK untuk mengurangi pencarian. SQL Server tidak melakukan ini secara otomatis.
Edit
Karena tautan sekarang tampaknya sudah mati (pujian kepada Chris karena memperhatikan) , berikut ini menunjukkan inti mengapa kunci asing dapat meningkatkan (dan melukai) kinerja.
Bisakah kunci Asing meningkatkan kinerja
sumber
Kunci asing adalah konsep DBMS untuk memastikan integritas basis data.
Setiap implikasi / peningkatan kinerja akan spesifik untuk teknologi database yang digunakan dan sekunder untuk tujuan kunci asing.
Ini adalah praktik yang baik dalam SQL Server untuk memastikan bahwa semua kunci asing setidaknya memiliki indeks non-cluster.
Saya harap ini menjelaskan semuanya untuk Anda tetapi jangan ragu untuk meminta detail lebih lanjut.
sumber
Taruhan performa terbaik Anda adalah dengan menggunakan Indeks pada bidang yang sering Anda gunakan. Jika Anda menggunakan SQL Server, Anda dapat menggunakan profiler untuk membuat profil basis data tertentu dan mengambil file yang di-output dan menggunakan penyetelan penyetelan untuk menerima rekomendasi tempat menempatkan indeks Anda. Saya juga suka menggunakan profiler untuk membersihkan prosedur tersimpan yang sudah berjalan lama, saya memiliki sepuluh daftar pelaku terburuk yang saya terbitkan setiap minggu, membuat orang jujur: D.
sumber
Anda dapat menggunakannya untuk membantu membuat kueri lebih efisien. Itu memungkinkan Anda untuk merestrukturisasi permintaan dalam SQL Server untuk menggunakan gabungan luar daripada yang dalam yang menghapus sql server necesity karena harus memeriksa apakah ada nol di kolom. Anda tidak perlu memasukkan kualifikasi itu karena hubungan kunci asing sudah memasukkan itu untuk Anda.
Jadi ini:
Menjadi ini:
Ini tidak harus membuat kinerja besar dalam kueri kecil, tetapi ketika tabel menjadi besar itu bisa lebih efisien.
sumber
Untuk MySQL 5.7, itu pasti dapat mempercepat permintaan yang melibatkan banyak gabungan dengan sangat baik!
Saya menggunakan 'jelaskan' untuk memahami permintaan saya dan menemukan bahwa saya bergabung dengan 4-5 tabel - di mana tidak ada kunci yang digunakan sama sekali. Saya tidak melakukan apa pun selain menambahkan kunci asing ke tabel ini dan hasilnya adalah pengurangan 90% pada waktu buka. Kueri yang membutuhkan> 5s sekarang membutuhkan 500ms atau kurang.
Itu adalah peningkatan BESAR!
DAN, seperti yang disebutkan orang lain, Anda mendapatkan bonus tambahan untuk memastikan integritas relasional.
Selain itu, memastikan integritas referensial memiliki manfaat kinerja sendiri. Ini memiliki efek urutan kedua untuk memastikan bahwa tabel yang memiliki kunci asing 'terkini' dengan tabel asing. Katakanlah Anda memiliki tabel pengguna dan tabel komentar, dan Anda melakukan beberapa statistik pada tabel komentar. Mungkin jika Anda sulit menghapus pengguna, Anda tidak ingin komentar mereka lagi.
sumber
Menambahkan kunci asing dalam tabel tidak akan meningkatkan kinerja, hanya mengatakan jika Anda memasukkan catatan dalam basis data tabel ProductCategories akan mencoba menemukan kolom kunci asing memiliki nilai yang ada di nilai kunci utama tabel produk, ini terlihat, operasi adalah overhead pada database Anda setiap kali Anda menambahkan entri baru di tabel ProductCategories. Jadi dengan menambahkan kunci asing tidak akan meningkatkan kinerja basis data Anda tetapi akan menjaga integritas basis data Anda. Ya itu akan meningkatkan kinerja Anda db jika Anda memeriksa integritas menggunakan kunci asing alih-alih menjalankan banyak pertanyaan untuk memeriksa catatan ada di database dalam program Anda.
sumber
Saya tidak tahu banyak tentang SQL server, tetapi dalam kasus Oracle, memiliki kolom kunci asing mengurangi kinerja pemuatan data. Itu karena database perlu memeriksa integritas data untuk setiap sisipan. Dan ya, seperti yang telah disebutkan, memiliki indeks pada kolom kunci asing adalah praktik yang baik.
sumber
Pada SQL Server 2008 kunci asing dapat mempengaruhi kinerja dengan mempengaruhi cara mesin database memilih untuk mengoptimalkan permintaan. Rujuk ke Star Join Heuristics di artikel berikut: https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx
sumber