Hal pertama yang harus Anda ketahui adalah bahwa indeks adalah cara untuk menghindari pemindaian tabel lengkap untuk mendapatkan hasil yang Anda cari.
Ada berbagai jenis indeks dan mereka diterapkan di lapisan penyimpanan, jadi tidak ada standar di antara mereka dan mereka juga bergantung pada mesin penyimpanan yang Anda gunakan.
InnoDB dan indeks B + Tree
Untuk InnoDB, tipe indeks yang paling umum adalah indeks berbasis B + Tree, yang menyimpan elemen dalam urutan diurutkan. Selain itu, Anda tidak harus mengakses tabel sebenarnya untuk mendapatkan nilai yang diindeks, yang membuat kueri Anda kembali dengan cara yang lebih cepat.
"Masalah" tentang tipe indeks ini adalah Anda harus meminta nilai paling kiri untuk menggunakan indeks. Jadi, jika indeks Anda memiliki dua kolom, ucapkan last_name dan first_name, urutan yang Anda query bidang ini sangat penting .
Jadi, diberikan tabel berikut:
CREATE TABLE person (
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
INDEX (last_name, first_name)
);
Kueri ini akan memanfaatkan indeks:
SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"
Tapi yang berikut tidak mau
SELECT last_name, first_name FROM person WHERE first_name = "Constantine"
Karena Anda menanyakan first_name
kolom terlebih dahulu dan itu bukan kolom paling kiri dalam indeks.
Contoh terakhir ini bahkan lebih buruk:
SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"
Karena sekarang, Anda membandingkan bagian paling kanan dari bidang paling kanan dalam indeks.
Indeks hash
Ini adalah tipe indeks berbeda yang sayangnya, hanya dukungan backend memori. Ini kilat cepat tetapi hanya berguna untuk pencarian penuh, yang berarti Anda tidak dapat menggunakannya untuk operasi seperti >
, <
atau LIKE
.
Karena ini hanya berfungsi untuk backend memori, Anda mungkin tidak akan sering menggunakannya. Kasus utama yang dapat saya pikirkan saat ini adalah yang Anda buat tabel sementara di memori dengan satu set hasil dari pilih lain dan melakukan banyak pilihan lain dalam tabel sementara ini menggunakan indeks hash.
Jika Anda memiliki VARCHAR
bidang besar , Anda dapat "meniru" penggunaan indeks hash saat menggunakan B-Tree, dengan membuat kolom lain dan menyimpan hash dari nilai besar di atasnya. Katakanlah Anda menyimpan url di bidang dan nilainya cukup besar. Anda juga bisa membuat bidang bilangan bulat yang disebut url_hash
dan menggunakan fungsi hash seperti CRC32
atau fungsi hash lainnya untuk meng-hash url saat memasukkannya. Dan kemudian, ketika Anda perlu menanyakan nilai ini, Anda bisa melakukan sesuatu seperti ini:
SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");
Masalah dengan contoh di atas adalah bahwa karena CRC32
fungsi menghasilkan hash yang cukup kecil, Anda akan berakhir dengan banyak tabrakan dalam nilai hash. Jika Anda membutuhkan nilai yang tepat, Anda dapat memperbaiki masalah ini dengan melakukan hal berikut:
SELECT url FROM url_table
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";
Ini masih layak untuk hash hal bahkan jika angka tumbukan tinggi karena Anda hanya akan melakukan perbandingan kedua (string satu) terhadap hash yang diulang.
Sayangnya, menggunakan teknik ini, Anda masih perlu menekan tabel untuk membandingkan url
bidang.
Bungkus
Beberapa fakta yang dapat Anda pertimbangkan setiap kali Anda ingin berbicara tentang pengoptimalan:
Perbandingan integer jauh lebih cepat daripada perbandingan string. Ini dapat diilustrasikan dengan contoh tentang persaingan indeks hash di InnoDB
.
Mungkin, menambahkan langkah-langkah tambahan dalam suatu proses membuatnya lebih cepat, bukan lebih lambat. Itu dapat diilustrasikan oleh fakta bahwa Anda dapat mengoptimalkan a SELECT
dengan membaginya menjadi dua langkah, membuat yang pertama menyimpan nilai dalam tabel di-memori yang baru dibuat, dan kemudian menjalankan kueri yang lebih berat di tabel kedua ini.
MySQL memiliki indeks lain juga, tapi saya pikir B + Tree adalah yang paling banyak digunakan dan hash adalah hal yang baik untuk diketahui, tetapi Anda dapat menemukan yang lain di dokumentasi MySQL .
Saya sangat menyarankan Anda untuk membaca buku "MySQL Kinerja Tinggi", jawaban di atas pasti didasarkan pada bab tentang indeks.