sql >> Databasteknik >  >> RDS >> Mysql

Betyder jokertecken i kolumnen längst till vänster i det sammansatta indexet att återstående kolumner i indexet inte används i indexsökning (MySQL)?

Här är dina frågor. Flertal. Genom att omformulera dem (med "med andra ord") är de bara olika frågor. Att göra det gör det inte nödvändigtvis lättare för svarande. Tvärtom.

F1:[Titelfråga] Betyder jokertecken i kolumnen längst till vänster i det sammansatta indexet att återstående kolumner i indexet inte används i indexsökning (MySQL)?

A1:Nej, det betyder inte det.

F2:Betyder jokertecken som används i efternamnsvillkoret att förnamnsvillkoret inte kommer att användas för att ytterligare hjälpa MySQL att hitta index?

A2:Nej, det betyder inte det. Plus svansen på den frågan är tvetydig. Den vet redan vilket index som ska användas som kan vara ett utlöpare svar på en sådan vaghet.

F3:Med andra ord, genom att sätta ett jokertecken på efternamnsvillkoret kommer MySQL bara att göra en partiell indexuppslagning (och ignorerar villkor som anges i kolumnerna till höger om efternamn)?

S3:Nej. Kolumnerna längst till höger serveras från indexet som liknar en täckande indexstrategi som drar nytta av den långsamma uppslagningen av datasidor.

F4:...skulle Exempel-1 vara snabbare än Exempel-2?

A4:Ja. Det är ett täckande index när det gäller dessa kolumner. Se täckande index.

Som en sida om Q4. Det är irrelevant om det är en PK eller icke-PK. Det finns förmodligen ett dussin skäl till varför det som PK skulle vara fruktansvärt för din ansökan.

Originalsvar nedan:

med endast en sammansatt nyckel på (last_name,first_name) och en fråga som du nämner

WHERE first_name LIKE 'joh%'

... Det kommer inte att använda indexet alls. Det kommer att göra en tabellskanning. På grund av frånvaron av

  • en enda kolumnnyckel på first_name
  • en sammansatt nyckel med first_name längst till vänster

Så bordsskanning här kommer vi.

Se manualsidan Multiple-column Indexes a> att läsa mer. Och fokusera på den left-most begreppet det. Gå faktiskt till den sidan och sök på ordet left .

Se manualsidan på Explain anläggning i mysql. Även artikeln Använda Explain för att skriva bättre Mysql-frågor a> .

Redigera

Det har gjorts några ändringar i frågan sedan jag var här för en timme eller två sedan. Jag lämnar dig med följande. Kör din faktiska fråga genom att förklara och dechiffrera genom Using Explain ... länk ovan eller annan referens

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 återger voodoo-nummer för rows . Voodoo? Ja, eftersom en fråga som potentiellt kommer att köras i en timme frågar du explain för att ge dig en otydlig räkning, kör inte den, och ge dig det svaret på 2 sekunder eller mindre. Se inte att dessa är verkliga antal för kriterier när det körs på riktigt, utan att 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. Hur MID() fungerar i MariaDB

  2. php:vända mysql_real_escape_strings effekter på binär

  3. Solr 4.6.0 DataImportHandler snabbar upp prestandan

  4. SQLiteOpenHelper:metoden onCreate() anropas inte på fysisk enhet