Strategi pencarian yang berbeda masuk akal untuk data yang berbeda. Secara khusus, pemindaian indeks (seperti rentang) sering kali harus dilakukan untuk benar-benar membaca baris. Pada titik tertentu, melakukan semua pencarian itu lebih lambat daripada tidak menggunakan indeks sama sekali.
Ambil contoh sepele, tabel dengan tiga kolom:id (kunci utama), nama (diindeks), ulang tahun. Katakanlah ia memiliki banyak data. Jika Anda meminta MySQL untuk mencari ulang tahun Bob, ia dapat melakukannya dengan cukup cepat:pertama, ia menemukan Bob dalam indeks nama (ini membutuhkan beberapa pencarian, log(n) di mana n adalah jumlah baris), kemudian satu pencarian tambahan untuk baca baris aktual dalam file data dan baca ulang tahun darinya. Itu sangat cepat, dan jauh lebih cepat daripada memindai seluruh tabel.
Selanjutnya, pertimbangkan untuk melakukan name like 'Z%'
. Itu mungkin porsi yang cukup kecil dari meja. Jadi masih lebih cepat untuk menemukan di mana Z mulai dalam indeks nama, kemudian untuk masing-masing mencari file data untuk membaca baris. (Ini adalah pemindaian jarak jauh).
Terakhir, pertimbangkan untuk menanyakan semua nama yang dimulai dengan M-Z. Itu mungkin sekitar setengah data. Itu bisa melakukan pemindaian jarak jauh, dan kemudian lot pencarian, tetapi mencari secara acak di atas file data dengan tujuan akhir membaca setengah baris tidak optimal:akan lebih cepat untuk hanya melakukan pembacaan berurutan besar atas file data. Jadi, dalam hal ini, indeks akan diabaikan.
Inilah yang Anda lihat—kecuali dalam kasus Anda, ada kunci lain yang dapat digunakan kembali. (Mungkin juga menggunakan indeks tanggal jika tidak memiliki yang lain, ia harus memilih indeks mana yang paling cepat. Hati-hati karena pengoptimal MySQL sering membuat kesalahan dalam hal ini.)
Jadi, singkatnya, ini diharapkan. Sebuah kueri tidak mengatakan bagaimana untuk mengambil data, lebih tepatnya dikatakan apa data untuk diambil. Pengoptimal database seharusnya menemukan cara tercepat untuk mengambilnya.
Anda mungkin menemukan indeks di keduanya kolom, dalam urutan (public_key,created_on_date) lebih disukai dalam kedua kasus, dan mempercepat kueri Anda. Ini karena MySQL hanya dapat menggunakan satu indeks per tabel (per kueri). Selain itu, tanggal berada di akhir karena pemindaian rentang hanya dapat dilakukan secara efisien pada kolom terakhir dalam indeks.
[InnoDB sebenarnya memiliki lapisan tipuan lain, saya percaya, tetapi itu hanya akan membingungkan intinya. Tidak ada bedanya dengan penjelasannya.]