Output EXPLAIN menunjukkan bahwa indeks saya tidak sedang digunakan

9

Saya telah mengatur meja saya dengan indeks hanya pada done_status (done_status = INT):

masukkan deskripsi gambar di sini

Ketika saya menggunakan:

EXPLAIN SELECT * FROM reminder  WHERE done_status=2

Saya mendapatkan ini kembali:

id select_type jenis tabel kemungkinan kunci key_len key baris ref ref Extra
1 SIMPLE pengingat SEMUA selesai_status NULL NULL NULL 5 Menggunakan di mana

Tetapi ketika saya mengeluarkan perintah ini:

EXPLAIN SELECT * FROM reminder  WHERE done_status=1

Saya mendapatkan yang berikut ini:

id select_type jenis tabel kemungkinan kunci key_len key baris ref ref Extra
1 pengingat SIMPLE ref done_status done_status 4 const 2   

The EXPLAINmenunjukkan saya bahwa ia menggunakan 5 baris, kedua kalinya 2 baris.

Saya tidak berpikir indeks digunakan, jika saya memahaminya dengan benar pertama kali harus memberi saya 3 baris. Apa yang saya lakukan salah?

SHOW INDEX FROM reminder:

Tabel Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Komentar Index_comment
pengingat 1 done_status 1 done_status A 5 NULL NULL BTREE

jelaskan diperpanjang:

id select_type jenis tabel kemungkinan kunci key_len key baris ref disaring Ekstra
1 pengingat SIMPLE ref done_status done_status 4 const 2 100.00

show warnings tidak menunjukkan minat.

TasostheGreat
sumber
Percayalah, indeksnya berfungsi. Tapi saya tidak bisa melihat apa pun dengan mudah di tangkapan layar Anda - dapatkah Anda melakukan "tampilkan indeks dari tabel Anda"
ya mengedit pertanyaan saya
silakan gunakan memuliakan \ G untuk skema dan menjelaskan hasil rencana, itu harus lebih mudah dibaca
ajreal
Yang tidak menarik dapat Anda ulangi dengan "jelaskan diperpanjang" dan "tampilkan peringatan" ini akan menunjukkan SQL mysql yang sebenarnya dipilih
@ajreal apa yang dimuliakan?

Jawaban:

4

Anda salah memahami bidang 'baris' itu. Ini adalah jumlah baris yang diperkirakan mysql perlu dibaca untuk memenuhi permintaan Anda. Nilai ini bisa sangat tidak akurat. Ini tidak berarti ini adalah jumlah baris dalam hasil - atau jumlah aktual baris yang dibaca oleh mysql


sumber
Begitu? Di mana saya mengatakan itu? Apa yang dipilih pengoptimal? Indeks masih berfungsi.
@ajreal Bukan berarti indeksnya rusak. Hanya pengoptimal yang memilih (dalam pikirannya) cara paling efisien untuk menanyakan data. Saya berasumsi OP mengharapkan kolom baris dalam EXPLAIN tepatnya. Itu tidak berarti indeks rusak - hanya saja mysql memilih untuk tidak menggunakannya (mungkin).
1
@ajreal: Saya kehilangan sesuatu dalam poin Anda. Kolom baris penjelasan tidak ada hubungannya dengan indeks, bukan? Mysql memilih untuk tidak menggunakan indeks (mungkin semua data dalam satu halaman). Tidak yakin saya mengerti maksud Anda? Optimasi kueri pada tabel 5 baris akan menghasilkan beberapa hasil 'aneh' karena cukup banyak tidak masalah bagaimana Anda mengoptimalkan.
Dalam hal ini siapa yang peduli indeks apa yang dipilih pengoptimal? Tidak ada yang salah dengan indeks itu sendiri, karena pengoptimal merasa seperti itu tidak memerlukannya - apa bedanya?
3

Dataran eksekusi pertama tidak menggunakan indeks pasti,
itu bisa menjadi information_schema.statistik pada indeks tidak mengejar data setelah beberapa operasi penulisan, atau tabel tidak diakses untuk waktu yang lama.

seperti yang dijelaskan di sini: - Dari mana MySQL Query Optimizer membaca statistik indeks?

untuk rencana eksekusi kedua, sepertinya information_schema.statistics sudah mengejar dan memperbaiki masalah kardinalitas NULL.

Oleh karena itu, jalankan kueri sesuai dengan pengoptimal indeks.

Untuk meja dengan baris kecil, tidak masalah.
Tetapi data akan tumbuh, pengembang harus selalu melakukan pemeriksaan ini,
dan melakukan tabel analisis yang diperlukan ketika menjumpai kardinalitas nol pada indeks.

nyata
sumber
0

Paket eksekusi pertama tidak menggunakan indeks.

Dari Situs Referensi MySQL :

Kadang-kadang MySQL tidak menggunakan indeks, bahkan jika ada. Satu keadaan di mana ini terjadi adalah ketika pengoptimal memperkirakan bahwa menggunakan indeks akan membutuhkan MySQL untuk mengakses persentase yang sangat besar dari baris dalam tabel. (Dalam hal ini, pemindaian tabel kemungkinan akan jauh lebih cepat karena membutuhkan lebih sedikit upaya.) Namun, jika kueri tersebut menggunakan LIMIT untuk mengambil hanya beberapa baris, MySQL tetap menggunakan indeks, karena ia dapat lebih cepat menemukan beberapa baris untuk mengembalikan hasilnya.

Jika tabel Anda hanya memiliki 5 baris dan kueri Anda memilih 3 dari mereka, maka pengoptimal MySQL mengasumsikan bahwa lebih efisien untuk memindai seluruh tabel.

Matthew Sammut
sumber