Oto twoje pytania. Mnogi. Przeformułując je (z „innymi słowy”), są po prostu różnymi pytaniami. Takie postępowanie niekoniecznie ułatwia ratownikom. Wręcz przeciwnie.
P1:[Pytanie tytułowe] Czy symbol wieloznaczny w skrajnej lewej kolumnie indeksu złożonego oznacza, że pozostałe kolumny indeksu nie są używane w wyszukiwaniu indeksu (MySQL)?
O1:Nie, to nie znaczy.
P2:Czy symbol wieloznaczny użyty w warunku nazwisko oznacza, że warunek imię nie będzie dalej pomagał MySQL w znajdowaniu indeksów?
O2:Nie, to nie znaczy. Plus ogon tego pytania jest niejednoznaczny. Już wie, jakiego indeksu użyć, może być jedną z odgałęzień odpowiedzi na taką niejasność.
P3:Innymi słowy, umieszczając symbol wieloznaczny w warunku last_name, MySQL wykona tylko częściowe wyszukiwanie indeksu (i ignoruje warunki podane w kolumnach po prawej stronie last_name)?
O3:Nie. Kolumny z prawej strony są obsługiwane z indeksu podobnie do strategii indeksowania obejmującej, która korzysta z powolnego wyszukiwania stron danych.
P4:...czy Przykład-1 byłby szybszy niż Przykład-2?
A4:Tak. Jest to indeks pokrywający w odniesieniu do tych kolumn. Zobacz indeksy obejmujące.
Na marginesie dotyczące Q4. Nie ma znaczenia, czy jest to PK, czy nie-PK. Istnieje prawdopodobnie kilkanaście powodów, dla których to jako PK byłoby okropne dla twojej aplikacji.
Oryginalne odpowiedzi poniżej:
z tylko klucz złożony na (last_name,first_name)
i zapytanie, o którym wspomniałeś
WHERE first_name LIKE 'joh%'
... W ogóle nie użyje indeksu. Zrobi skan tabeli. Z powodu braku
- klucz pojedynczej kolumny w
first_name
- klucz złożony z
first_name
od lewej
Więc skan stołu, nadchodzimy.
Zapoznaj się ze stroną podręcznika Indeksy wielokolumnowe aby przeczytać więcej. I skup się na left-most
koncepcja tego. W rzeczywistości przejdź do tej strony i wyszukaj słowo left
.
Zobacz stronę podręcznika w Wyjaśnij obiekt w mysql. Również artykuł Korzystanie z wyjaśnienia do pisania lepszych zapytań Mysql .
Edytuj
Było kilka zmian w pytaniu, odkąd byłem tu godzinę lub dwie temu. Zostawię cię z następującymi. Uruchom rzeczywiste zapytanie przez wyjaśnienie i odszyfruj przez Using Explain ...
link powyżej lub inny odnośnik
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
renderuje liczby voodoo dla rows
. Wiara w czary? Tak, ponieważ zapytanie, które potencjalnie będzie działać przez godzinę, pytasz explain
aby dać ci rozmytą liczbę, nie uruchamiać jej i dać ci odpowiedź w ciągu 2 sekund lub mniej. Nie traktuj ich jako rzeczywistych #'s dla kryteriów, gdy jest uruchamiany w rzeczywistości, bez 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 |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+