Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Teks lengkap dan indeks komposit dan bagaimana pengaruhnya terhadap kueri

Jika saya memahami pertanyaan Anda, Anda tahu bahwa MATCH AGAINST menggunakan indeks FULLTEXT Anda dan Anda bertanya-tanya bagaimana MySQL menerapkan sisa klausa WHERE (mis. apakah ia melakukan pencarian tabel atau pencarian yang diindeks).

Inilah yang saya asumsikan tentang tabel Anda:tabel ini memiliki KUNCI UTAMA pada beberapa kolom id dan indeks FULLTEXT.

Jadi pertama-tama, MySQL tidak akan tidak pernah gunakan indeks FULLTEXT untuk klausa WHERE kota/negara bagian. Mengapa? Karena indeks FULLTEXT hanya berlaku dengan MATCH AGAINST. Lihat di sini dalam paragraf setelah butir pertama (bukan butir Daftar Isi).

EDIT: Dalam kasus Anda, dengan asumsi tabel Anda tidak hanya memiliki 10 baris, MySQL akan menerapkan indeks FULLTEXT untuk MATCH AGAINST Anda, kemudian lakukan pemindaian tabel pada hasil tersebut untuk menerapkan kota/negara bagian WHERE.

Jadi bagaimana jika Anda menambahkan indeks BTREE ke kota dan negara bagian?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

Yah MySQL hanya bisa menggunakan satu indeks untuk kueri ini karena ini adalah pilihan sederhana. Ini akan salah satu gunakan TEKS LENGKAP atau BTREE. Perhatikan bahwa ketika saya mengatakan satu indeks, maksud saya satu definisi indeks, bukan satu kolom dalam indeks multi-bagian. Lagi pula, ini kemudian menimbulkan pertanyaan mana yang melakukannya digunakan?

Itu tergantung pada analisis tabel. MySQL akan mencoba untuk memperkirakan (berdasarkan statistik tabel dari TABEL OPTIMASI terakhir) indeks mana yang akan memangkas catatan terbanyak. Jika kota/negara bagian WHERE membuat Anda turun ke 10 catatan sedangkan MATCH AGAINST hanya membuat Anda turun ke 100, maka MySQL akan menggunakan indeks city__state pertama untuk kota/negara bagian WHERE lalu lakukan pemindaian tabel untuk MATCH AGAINST.

Di sisi lain, jika MATCH_AGAINST membuat Anda turun ke 10 catatan sementara kota/negara bagian WHERE membuat Anda turun menjadi hanya 1000, maka MySQL akan menerapkan indeks FULLTEXT terlebih dahulu dan tabel bisa untuk kota dan negara bagian.

Intinya adalah kardinalitas dari indeks Anda. Pada dasarnya, seberapa unik nilai yang akan masuk ke indeks Anda? Jika setiap catatan di tabel Anda memiliki kota yang disetel ke Oakland, maka itu bukan kunci yang sangat unik sehingga memiliki city ='Oakland' tidak benar-benar mengurangi jumlah catatan sebanyak itu untuk Anda. Dalam hal ini, kami mengatakan indeks city__state Anda memiliki kardinalitas rendah .

Akibatnya jika 90% dari kata-kata dalam indeks FULLTEXT Anda adalah "John", maka itu juga tidak banyak membantu Anda karena alasan yang sama persis.

Jika Anda mampu membayar ruang dan overhead UPDATE/DELETE/INSERT, saya akan merekomendasikan menambahkan indeks BTREE dan membiarkan MySQL memutuskan indeks mana yang ingin ia gunakan. Dalam pengalaman saya, dia biasanya melakukan pekerjaan yang sangat baik dalam memilih yang tepat.

Saya harap itu menjawab pertanyaan Anda.

EDIT: Sebagai tambahan, pastikan Anda memilih ukuran yang tepat untuk indeks BTREE Anda (dalam contoh saya, saya memilih 10 karakter pertama di kota). Ini jelas membuat dampak besar pada kardinalitas. Jika Anda memilih kota(1), maka jelas Anda akan mendapatkan kardinalitas yang lebih rendah dibandingkan jika Anda memilih kota(10).

EDIT2: Rencana kueri (estimasi) MySQL yang indeksnya paling banyak memangkas catatan adalah apa yang Anda lihat di EXPLAIN.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLSTATE[HY000] [2002] Tidak ada kesalahan file atau direktori saat memigrasi tabel di Laravel

  2. MySql:apakah mungkin untuk 'SUM JIKA' atau 'HITUNG JIKA'?

  3. Mysql Bagaimana hanya memilih dari kolom jika kolom ada

  4. Apakah mungkin membuat kolom di MySQL dengan ekspresi sebagai nilai default?

  5. Pustaka tidak dimuat:kesalahan libmysqlclient.16.dylib saat mencoba menjalankan 'rails server' di OS X 10.6 dengan permata mysql2