Apakah MySQL mengindeks kolom kunci asing secara otomatis?

261

Apakah MySQL mengindeks kolom kunci asing secara otomatis?

Dónal
sumber

Jawaban:

229

Ya, tetapi hanya menyala . Innodb saat ini merupakan satu-satunya format tabel yang dikirimkan yang menerapkan kunci asing.

Grant Limberg
sumber
1
Apakah Anda memiliki alasan untuk meyakini bahwa MySQL akan pernah mengizinkan kunci asing pada kolom yang tidak diindeks untuk jenis tabel lainnya?
Robert Gamble
Saya benar-benar tidak bisa menjawabnya. Anda mungkin ingin mencari mesin penyimpanan Maria dan Falcon yang akan dirilis di MySQL 6.0 dan melihat apakah mereka mendukung kunci asing pada kolom yang tidak diindeks.
Grant Limberg
Ternyata ini tidak benar. Saya memiliki tabel besar (1 juta catatan) dan menghitung (*) di mana fkey =? akan memakan waktu 15 detik. Menambahkan indeks pada kolom fkey, dan semuanya berjalan di bawah satu detik sekarang.
AbiusX
Eksperimen yang sama dengan tabel lain dan 10 juta catatan. Ini adalah ofc MySQL 5.1 InnoDB. Tabel memiliki tiga bidang, satu bilangan bulat kunci, yang lain sudah diindeks. Yang ketiga adalah kunci asing ke kunci utama dari tabel lain. Tanpa menambahkan indeks eksplisit, pencarian butuh beberapa detik di sini. Tampilkan indeks dari tabel juga tidak menunjukkan indeks di atasnya.
AbiusX
@AususX 5.1 mungkin terlalu tua, lihat jawaban MrAlexander di bawah ini.
e2-e4
131

Rupanya indeks dibuat secara otomatis seperti yang ditentukan dalam tautan yang telah diposting robert .

InnoDB membutuhkan indeks pada kunci asing dan kunci referensi sehingga pemeriksaan kunci asing dapat cepat dan tidak memerlukan pemindaian tabel. Dalam tabel referensi, harus ada indeks di mana kolom kunci asing terdaftar sebagai kolom pertama dalam urutan yang sama. Indeks semacam itu dibuat pada tabel referensi secara otomatis jika tidak ada. (Ini berbeda dengan beberapa versi yang lebih lama, di mana indeks harus dibuat secara eksplisit atau pembuatan batasan kunci asing akan gagal.) Index_name, jika diberikan, digunakan seperti yang dijelaskan sebelumnya.

InnoDB dan Kendala KUNCI ASING

Justin Johnson
sumber
9
+1 jawaban yang jauh lebih baik daripada yang dipilih karena memberikan bukti dari dokumen
Gaz_Edge
6
Teks yang dikutip tampaknya tidak dimasukkan dalam dokumen MySQL lagi, membuatnya tidak jelas apakah ini masih benar atau tidak.
Courtney Miles
7
@ user2045006 Anda dapat merujuk ke doc 5.0 juga doc 5.6 untuk teks yang dikutip tepat
sactiw
1
Dalam dokumen saat ini, hanya ada sedikit perubahan dalam teks (saya menganggap artinya serupa):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto
20

Ya, lihat InnoDB dan Kendala KUNCI ASING .

Robert Gamble
sumber
4
Jawaban ini adalah contoh bagus mengapa jawaban tidak boleh hanya terdiri dari tautan ke jawaban yang mungkin. Saat ini, halaman tertaut tidak menjawab pertanyaan sama sekali.
Mike
1
Harap tambahkan semua informasi ke jawaban itu sendiri alih-alih hanya memposting tautan
Nico Haase
11

Anda tidak mendapatkan indeks secara otomatis jika Anda melakukan ALTER TABLE (bukan CREATE TABLE), setidaknya menurut dokumen (tautannya untuk 5.1 tetapi sama untuk 5.5):

[...] Saat Anda menambahkan batasan kunci asing ke tabel menggunakan ALTER TABLE, ingat untuk membuat indeks yang diperlukan terlebih dahulu.

Thomas Lundström
sumber
2
Saya juga mencoba MySQL 5.6 dan MariaDB 10 dan ALTER TABLE membuat indeks. Sangat menarik bahwa mysqlindexcheck melaporkan indeks itu sebagai "indeks redundan". Saya mencoba untuk menjatuhkannya tetapi saya mendapatkan kesalahan berikut: "ERROR 1553 (HY000): Tidak dapat menjatuhkan indeks 'index_name': diperlukan dalam batasan kunci asing". Jadi, tidak mungkin untuk menjatuhkan indeks itu dan mempertahankan kunci asing.
Ciprian Stoica
Anda mungkin ingin merevisi jawaban Anda. MySQL selalu membuat indeks untuk mempercepat pemeriksaan kunci asing jika belum ada . Dokumen berusaha memberi tahu Anda bahwa membuat indeks sebelum batasan kunci asing mungkin mempercepat sedikit. Misalnya, indeks kunci komposit yang dapat berfungsi sebagai indeks untuk pemeriksaan kunci asing dapat digunakan oleh InnoDB alih-alih secara otomatis menghasilkan indeks yang berlebihan.
BMiner
7

Bagi mereka yang mencari kutipan dari 5.7 dokumen :

MySQL memerlukan indeks pada kunci asing dan kunci referensi sehingga pemeriksaan kunci asing dapat cepat dan tidak memerlukan pemindaian tabel. Dalam tabel referensi, harus ada indeks di mana kolom kunci asing terdaftar sebagai kolom pertama dalam urutan yang sama. Indeks semacam itu dibuat pada tabel referensi secara otomatis jika tidak ada. Indeks ini mungkin turun secara diam-diam nanti, jika Anda membuat indeks lain yang dapat digunakan untuk menegakkan batasan kunci asing. index_name, jika diberikan, digunakan seperti yang dijelaskan sebelumnya.

Fahmi
sumber
4

Sebagaimana dinyatakan itu untuk InnoDB. Pada awalnya saya pikir itu aneh bahwa banyak lainnya (khususnya MS SQL dan DB2) tidak. Pemindaian TableSpace hanya lebih baik daripada pemindaian indeks ketika ada sangat sedikit baris tabel - jadi untuk sebagian besar kasus kunci asing ingin diindeks. Lalu itu semacam memukul saya - ini tidak selalu berarti itu harus menjadi indeks yang berdiri sendiri (satu kolom) - di mana ia berada di Indeks FK otomatis MySQL. Jadi, mungkin itu adalah alasan MS SQL, DB2 (Oracle saya tidak yakin), dll. Serahkan saja pada DBA; setelah semua indeks pada tabel besar dapat menyebabkan masalah dengan kinerja dan ruang.

Wolf5370
sumber
Anda memunculkan poin bagus tentang indeks kunci komposit; Namun, MySQL akan secara otomatis / diam-diam menjatuhkan indeks kunci tunggal yang dibuat secara otomatis jika indeks kunci komposit yang baru dibuat memenuhi kewajiban membuat kunci asing diperiksa dengan cepat. Sejujurnya, saya tidak tahu mengapa MS SQL, DB2, dan lainnya tidak melakukan ini. Mereka punya sedikit alasan. Saya tidak bisa memikirkan kasus penggunaan di mana indeks yang dibuat secara otomatis pada kunci asing akan berbahaya.
BMiner
2

Ya, Innodbberikan ini. Anda dapat memasukkan nama kunci asing setelah FOREIGN KEYklausa atau membiarkannya membiarkan MySQL membuat nama untuk Anda. MySQL secara otomatis membuat indeks dengan foreign_key_namenama tersebut.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
Navrattan Yadav
sumber
0

Ya, kunci asing indeks Mysql secara otomatis ketika Anda membuat tabel yang memiliki kunci asing untuk yang lain.

giapnh
sumber
-2

Kunci indeks tidak dapat digunakan secara otomatis

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Nama tabel yang telah Anda buat misalnya foto dan KUNCI ASING misalnya photograph_id. Kode harus seperti ini

ALTER TABLE photographs ADD INDEX (photograph_id);
Ali Raza
sumber