Mysql
 sql >> Baza danych >  >> RDS >> Mysql

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)?

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 |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zamów używając polskich liter

  2. Jak mogę policzyć posty, które mają zerowy lub pozytywny wynik głosów?

  3. Jak sprawdzić, czy data mieści się w przedziale w PHP lub MySQL?

  4. sprawdź dostępność pokoju z SQL

  5. Sortowanie danych wyjściowych wiersza SQL według dowolnej kolejności?