Berikut adalah beberapa hal yang akan saya coba, dalam rangka meningkatkan kesulitan:
(lebih mudah) - Pastikan Anda memiliki indeks penutup yang tepat
CREATE INDEX ix_temp ON relations (relation_title, object_title);
Ini harus memaksimalkan kinerja mengingat skema Anda yang ada, karena (kecuali versi pengoptimal mySQL Anda benar-benar bodoh!) Ini akan meminimalkan jumlah I/O yang diperlukan untuk memenuhi permintaan Anda (tidak seperti jika indeks berada dalam urutan terbalik di mana seluruh indeks harus dipindai) dan itu akan mencakup kueri sehingga Anda tidak perlu menyentuh indeks berkerumun.
(sedikit lebih sulit) - pastikan bidang varchar Anda sekecil mungkin
Salah satu tantangan kinerja dengan indeks varchar di MySQL adalah, saat memproses kueri, ukuran penuh bidang yang dideklarasikan akan ditarik ke dalam RAM. Jadi, jika Anda memiliki varchar (256) tetapi hanya menggunakan 4 karakter, Anda masih membayar penggunaan RAM 256-byte saat kueri sedang diproses. Aduh! Jadi, jika Anda dapat mengecilkan batas varchar dengan mudah, ini akan mempercepat kueri Anda.
(lebih sulit) - Normalisasi
30% dari baris Anda yang memiliki nilai string tunggal adalah seruan yang jelas untuk menormalkan ke tabel lain sehingga Anda tidak menduplikasi string jutaan kali. Pertimbangkan untuk menormalkan menjadi tiga tabel dan menggunakan ID bilangan bulat untuk menggabungkannya.
Dalam beberapa kasus, Anda dapat menormalkan di bawah selimut dan menyembunyikan normalisasi dengan tampilan yang cocok dengan nama tabel saat ini... maka Anda hanya perlu membuat kueri INSERT/UPDATE/DELETE Anda mengetahui normalisasi tetapi dapat membiarkan SELECT Anda sendiri .
(paling sulit) - Hash kolom string Anda dan indeks hashnya
Jika normalisasi berarti mengubah terlalu banyak kode, tetapi Anda dapat mengubah skema sedikit, Anda mungkin ingin mempertimbangkan untuk membuat hash 128-bit untuk kolom string Anda (menggunakan Fungsi MD5 ). Dalam hal ini (tidak seperti normalisasi), Anda tidak perlu mengubah semua kueri Anda, hanya INSERT dan beberapa SELECT. Bagaimanapun, Anda ingin melakukan hash pada bidang string Anda, dan kemudian membuat indeks pada hash, mis.
CREATE INDEX ix_temp ON relations (relation_title_hash, object_title_hash);
Perhatikan bahwa Anda harus bermain-main dengan SELECT untuk memastikan Anda melakukan perhitungan melalui indeks hash dan tidak menarik indeks berkerumun (diperlukan untuk menyelesaikan nilai teks aktual dari object_title untuk memenuhi kueri).
Juga, jika relation_title memiliki ukuran varchar yang kecil tetapi judul objek memiliki ukuran yang panjang, maka Anda hanya dapat meng-hash object_title dan membuat indeks pada (relation_title, object_title_hash)
.
Perhatikan bahwa solusi ini hanya membantu jika salah satu atau kedua bidang ini sangat panjang dibandingkan dengan ukuran hash.
Perhatikan juga bahwa ada sensitivitas huruf besar/penyatuan dampak yang menarik dari hashing, karena hash dari string huruf kecil tidak sama dengan hash dari string huruf besar. Jadi, Anda harus memastikan bahwa Anda menerapkan kanonikalisasi ke string sebelum melakukan hashing-- dengan kata lain, hanya hash huruf kecil jika Anda menggunakan DB yang tidak peka huruf besar-kecil. Anda juga mungkin ingin memangkas spasi dari awal atau akhir, tergantung pada bagaimana DB Anda menangani spasi awal/akhir.