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

Apakah wildcard di kolom paling kiri indeks komposit berarti kolom yang tersisa dalam indeks tidak digunakan dalam pencarian indeks (MySQL)?

Berikut adalah pertanyaan Anda. Jamak. Dengan mengulanginya (dengan "dengan kata lain"), itu hanyalah pertanyaan yang berbeda. Melakukan hal itu tidak selalu membuat responden lebih mudah. Sebaliknya.

Q1:[Pertanyaan judul] Apakah wildcard di kolom paling kiri indeks komposit berarti kolom yang tersisa dalam indeks tidak digunakan dalam pencarian indeks (MySQL)?

A1:Tidak, bukan begitu.

T2:Apakah wildcard yang digunakan dalam kondisi last_name berarti bahwa kondisi first_name tidak akan digunakan untuk membantu MySQL menemukan indeks lebih lanjut?

A2:Tidak, bukan begitu. Ditambah ekor pertanyaan itu ambigu. Ia sudah tahu Indeks apa yang digunakan bisa menjadi salah satu jawaban cabang untuk ketidakjelasan seperti itu.

Q3:Dengan kata lain, dengan meletakkan wildcard pada kondisi last_name MySQL hanya akan melakukan pencarian indeks parsial (dan mengabaikan kondisi yang diberikan pada kolom di sebelah kanan last_name)?

J3:Tidak. Kolom paling kanan disajikan dari indeks serupa dengan strategi indeks penutup yang diuntungkan dari lambatnya pencarian halaman data.

Q4:...akankah Contoh-1 lebih cepat dari Contoh-2?

A4:Ya. Ini adalah indeks penutup sehubungan dengan kolom-kolom itu. Lihat indeks penutup.

Sebagai tambahan tentang Q4. Tidak relevan apakah itu PK atau non-PK. Mungkin ada selusin alasan mengapa itu sebagai PK mengerikan untuk aplikasi Anda.

Jawaban asli di bawah ini:

dengan hanya kunci komposit pada (last_name,first_name) dan kueri seperti yang Anda sebutkan

WHERE first_name LIKE 'joh%'

... Itu tidak akan menggunakan indeks sama sekali. Ini akan melakukan pemindaian tabel. Karena tidak adanya

  • kunci kolom tunggal pada first_name
  • kunci gabungan dengan first_name paling kiri

Jadi, pemindaian tabel, kami datang.

Silakan lihat halaman Manual Indeks Beberapa Kolom untuk membaca lebih lanjut. Dan fokus pada left-most konsep itu. Bahkan, buka halaman itu, dan cari kata left .

Lihat Halaman Manual di Jelaskan fasilitas di mysql. Juga artikel Menggunakan Jelaskan untuk Menulis Kueri Mysql yang Lebih Baik .

Sunting

Ada beberapa suntingan untuk pertanyaan itu sejak saya berada di sini satu atau dua jam yang lalu. Saya akan meninggalkan Anda dengan yang berikut ini. Jalankan kueri Anda yang sebenarnya melalui penjelasan, dan uraikan melalui Using Explain ... link di atas atau referensi lain

drop table myNames;
create table myNames
(   id int auto_increment primary key,
    lastname varchar(100) not null,
    firstname varchar(100) not null,
    col4 int not null,
    key(lastname,firstname)
);
truncate table myNames;
insert myNames (lastName,firstName,col4) values
('Smith','John',1),('Smithers','JohnSomeone',1),('Smith3','John4324',1),('Smi','Jonathan',1),('Smith123x$FA','Joh',1),('Smi3jfif','jkdid',1),('r3','fe2',1);

insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;

select count(*) from myNames; 
-- 458k rows

select count(*)
from myNames
where lastname like 'smi%';
-- 393216 rows

select count(*)
from myNames
where lastname like 'smi%' and firstname like 'joh%';
-- 262144 rows

Explain merender nomor voodoo untuk rows . Voodoo? Ya, karena kueri yang berpotensi berjalan selama satu jam, Anda meminta explain untuk memberi Anda hitungan kabur, bukan menjalankannya, dan memberi Anda jawaban itu dalam 2 detik atau kurang. Jangan menganggap ini sebagai hitungan nyata # untuk kriteria ketika dijalankan secara nyata, tanpa explain .

explain 
select count(*) 
from myNames 
where lastname like 'smi%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows   | Extra                    |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | myNames | range | lastname      | lastname | 302     | NULL | 233627 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+

explain 
select count(*) 
from myNames 
where lastname like 'smi%' and firstname like 'joh%' and col4=1;
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows   | Extra                    |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | myNames | range | lastname      | lastname | 604     | NULL | 233627 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+


-- the below chunk is interest. Look at the Extra column

explain 
select count(*) 
from myNames 
where lastname like 'smi%' and firstname like 'joh%' and col4=1;
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | myNames | ALL  | lastname      | NULL | NULL    | NULL | 457932 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

explain 
select count(*) 
from myNames 
where firstname like 'joh%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows   | Extra                    |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | myNames | index | NULL          | lastname | 604     | NULL | 453601 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+


analyze table myNames;
+----------------------+---------+----------+----------+
| Table                | Op      | Msg_type | Msg_text |
+----------------------+---------+----------+----------+
| so_gibberish.mynames | analyze | status   | OK       |
+----------------------+---------+----------+----------+

select count(*) 
from myNames where left(lastname,3)='smi';
-- 393216 -- the REAL #
select count(*) 
from myNames where left(lastname,3)='smi' and left(firstname,3)='joh';
-- 262144 -- the REAL #

explain 
select lastname,firstname 
from myNames  
where lastname like 'smi%' and firstname like 'joh%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table   | type  | possible_keys | key      | key_len | ref  | rows   | Extra                    |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | myNames | range | lastname      | lastname | 604     | NULL | 226800 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. koneksi mysqli tidak berfungsi di dalam fungsi?

  2. Kode kesalahan 1064, status SQL 42000:Anda memiliki kesalahan dalam sintaks SQL Anda;

  3. Dapatkan nilai MAX dari satu kolom dan MIN dari kolom lain

  4. MySQL PHP count(*) mengembalikan sesuatu yang aneh

  5. Konversi file dari Cp1252 ke utf -8 java