sql >> Database >  >> RDS >> Mysql

Betekent een jokerteken in de meest linkse kolom van de samengestelde index dat de resterende kolommen in de index niet worden gebruikt bij het opzoeken van indexen (MySQL)?

Hier zijn uw vragen. Meervoud. Door ze te herformuleren (met "met andere woorden") zijn het gewoon andere vragen. Dit maakt het niet noodzakelijkerwijs gemakkelijker voor responders. Integendeel.

V1:[Titelvraag] Betekent wildcard in de meest linkse kolom van de samengestelde index dat de resterende kolommen in de index niet worden gebruikt bij het opzoeken van de index (MySQL)?

A1:Nee, dat betekent dat niet.

Vraag 2:Betekent het jokerteken dat wordt gebruikt in de voorwaarde achternaam, dat de voorwaarde voornaam niet wordt gebruikt om MySQL verder te helpen bij het vinden van indexen?

A2:Nee, dat betekent dat niet. Bovendien is de staart van die vraag dubbelzinnig. Het weet al welke Index te gebruiken als een uitloper van een dergelijke vaagheid.

Q3:Met andere woorden, door een wildcard op de voorwaarde achternaam te plaatsen, zal MySQL slechts een gedeeltelijke indexzoekopdracht uitvoeren (en negeert voorwaarden die in de kolommen rechts van achternaam staan)?

A3:Nee. De meest rechtse kolommen worden weergegeven vanuit de index, vergelijkbaar met een dekkende indexstrategie die profiteert van de traagheid van het opzoeken van gegevenspagina's.

V4:...zou voorbeeld-1 sneller zijn dan voorbeeld-2?

A4:Ja. Het is een dekkende index met betrekking tot die kolommen. Zie dekkende indexen.

Even terzijde met betrekking tot Q4. Het maakt niet uit of het een PK of niet-PK is. Er zijn waarschijnlijk een tiental redenen waarom dat als PK vreselijk zou zijn voor uw toepassing.

Oorspronkelijke antwoord(en) hieronder:

met alleen een samengestelde sleutel op (last_name,first_name) en een vraag zoals je zegt

WHERE first_name LIKE 'joh%'

... Het zal de index helemaal niet gebruiken. Het zal een tabelscan uitvoeren. Door de afwezigheid van

  • een enkele kolomsleutel op first_name
  • een samengestelde sleutel met first_name meest linkse

Dus tafel scan, hier komen we.

Zie de handleiding pagina Multiple-Column Indexes om meer te lezen. En focus op de left-most begrip ervan. Ga in feite naar die pagina en zoek op het woord left .

Zie de pagina met de handleiding op de Uitleggen faciliteit in mysql. Ook het artikel Uitleg gebruiken om betere Mysql-query's te schrijven .

Bewerken

Er zijn een paar wijzigingen in de vraag geweest sinds ik hier een uur of twee geleden was. Ik laat u met het volgende achter. Voer uw eigenlijke zoekopdracht uit via Explain en ontcijfer met behulp van de Using Explain ... link hierboven of een andere referentie

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 geeft voodoo-nummers weer voor rows . Voodoo? Ja, want een zoekopdracht die mogelijk een uur duurt, vraagt ​​u explain om u een wazige telling te geven, niet uit te voeren, en u dat antwoord in 2 seconden of minder te geven. Beschouw dit niet als echte telling #'s voor criteria wanneer het echt wordt uitgevoerd, zonder 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. Controleren op een leeg resultaat (PHP, PDO en MySQL)

  2. Wat is de beste databasestructuur om meertalige gegevens te bewaren?

  3. Het minimaliseren van de impact van het verbreden van een IDENTITEIT-kolom - deel 2

  4. databasevragen in sql