MySQL memungkinkan Anda untuk menentukan indeks awalan yang berarti Anda menentukan karakter N pertama dari string asli untuk diindeks, dan triknya adalah memilih nomor N yang cukup panjang untuk memberikan selektivitas yang baik, tetapi cukup pendek untuk menghemat ruang. Awalan harus cukup panjang untuk membuat indeks hampir berguna jika Anda akan mengindeks seluruh kolom.
Sebelum kita melangkah lebih jauh, mari kita mendefinisikan beberapa istilah penting. Selektivitas indeks adalah rasio total nilai indeks yang berbeda dan jumlah baris . Berikut adalah satu contoh untuk tabel tes:
+-----+-----------+
| id | value |
+-----+-----------+
| 1 | abc |
| 2 | abd |
| 3 | adg |
+-----+-----------+
Jika kita hanya mengindeks karakter pertama (N = 1), maka tabel indeks akan terlihat seperti tabel berikut:
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| a | 1,2,3 |
+---------------+-----------+
Dalam hal ini, selektivitas indeks sama dengan IS = 1/3 = 0,33.
Sekarang mari kita lihat apa yang akan terjadi jika kita menambah jumlah karakter yang diindeks menjadi dua (N = 2).
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| ab | 1,2 |
| ad | 3 |
+---------------+-----------+
Dalam skenario ini IS = 2/3 = 0,66 yang berarti kami meningkatkan selektivitas indeks, tetapi kami juga meningkatkan ukuran indeks. Triknya adalah mencari angka minimal N yang akan menghasilkan selektivitas indeks maksimal .
Ada dua pendekatan yang dapat Anda lakukan perhitungan untuk tabel database Anda. Saya akan melakukan demonstrasi pada dump database ini .
Katakanlah kita ingin menambahkan kolom last_name di tabel karyawan ke indeks, dan kami ingin mendefinisikan angka terkecil N yang akan menghasilkan selektivitas indeks terbaik.
Pertama mari kita mengidentifikasi nama belakang yang paling sering:
select count(*) as cnt, last_name from employees group by employees.last_name order by cnt
+-----+-------------+
| cnt | last_name |
+-----+-------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Farris |
| 222 | Sudbeck |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Neiman |
| 218 | Mandell |
| 218 | Masada |
| 217 | Boudaillier |
| 217 | Wendorf |
| 216 | Pettis |
| 216 | Solares |
| 216 | Mahnke |
+-----+-------------+
15 rows in set (0.64 sec)
Seperti yang Anda lihat, nama belakang Baba adalah yang paling sering. Sekarang kita akan menemukan awalan last_name paling sering terjadi , dimulai dengan lima huruf awalan.
+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa |
| 758 | Mande |
| 711 | Schwa |
| 562 | Angel |
| 561 | Gecse |
| 555 | Delgr |
| 550 | Berna |
| 547 | Peter |
| 543 | Cappe |
| 539 | Stran |
| 534 | Canna |
| 485 | Georg |
| 417 | Neima |
| 398 | Petti |
| 398 | Duclo |
+-----+--------+
15 rows in set (0.55 sec)
Ada lebih banyak kejadian dari setiap awalan, yang berarti kita harus meningkatkan angka N hingga nilainya hampir sama seperti pada contoh sebelumnya.
Ini adalah hasil untuk N = 9
select count(*) as cnt, left(last_name,9) as prefix from employees group by prefix order by cnt desc limit 0,15;
+-----+-----------+
| cnt | prefix |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudailli |
| 216 | Cummings |
| 216 | Pettis |
+-----+-----------+
Ini adalah hasil untuk N = 10.
+-----+------------+
| cnt | prefix |
+-----+------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudaillie |
| 216 | Cummings |
| 216 | Pettis |
| 216 | Solares |
+-----+------------+
15 rows in set (0.56 sec)
Ini hasil yang sangat bagus. Ini berarti bahwa kita dapat membuat indeks pada kolom last_name dengan mengindeks hanya 10 karakter pertama. Dalam tabel definisi, last_name didefinisikan sebagai VARCHAR(16)
, dan ini berarti kami telah menyimpan 6 byte (atau lebih jika ada karakter UTF8 dalam nama belakang) per entri. Dalam tabel ini ada 1637 nilai berbeda dikalikan dengan 6 byte sekitar 9KB, dan bayangkan bagaimana angka ini akan tumbuh jika tabel kita berisi jutaan baris.
Anda dapat membaca cara-cara lain untuk menghitung jumlah N dalam indeks Prefixed posting saya di MySQL .
Menggunakan fungsi MD5 dan SHA1 untuk menghasilkan nilai yang harus diindeks juga bukan pendekatan yang baik . Mengapa? Baca di pos Bagaimana memilih tipe data yang tepat untuk kunci utama dalam database MySQL