Voici vos questions. Pluriel. En les reformulant (avec "en d'autres termes"), ce sont juste des questions différentes. Cela ne facilite pas nécessairement la tâche des intervenants. Au contraire.
Q1 :[Question relative au titre] Le caractère générique dans la colonne la plus à gauche de l'index composite signifie-t-il que les colonnes restantes de l'index ne sont pas utilisées dans la recherche d'index (MySQL) ?
A1 :Non, ça ne veut pas dire ça.
Q2 :Le caractère générique utilisé dans la condition last_name signifie-t-il que la condition first_name ne sera pas utilisée pour aider davantage MySQL à trouver des index ?
A2 :Non, ça ne veut pas dire ça. De plus, la queue de cette question est ambiguë. Il sait déjà quel index utiliser pourrait être une réponse dérivée à un tel flou.
Q3 :En d'autres termes, en mettant un caractère générique sur la condition last_name, MySQL ne fera qu'une recherche partielle dans l'index (et ignorera les conditions données dans les colonnes à droite de last_name) ?
A3 : Non. Les colonnes les plus à droite sont servies à partir de l'index, de la même manière qu'une stratégie d'index de couverture bénéficiant de la lenteur de la recherche des pages de données.
Q4 :...l'Exemple-1 serait-il plus rapide que l'Exemple-2 ?
R4 :Oui. Il s'agit d'un index de couverture en ce qui concerne ces colonnes. Voir les index de couverture.
En aparté concernant Q4. Peu importe qu'il s'agisse d'un PK ou d'un non-PK. Il y a probablement une douzaine de raisons pour lesquelles cela en tant que PK serait épouvantable pour votre application.
Réponse(s) originale(s) ci-dessous :
avec uniquement une clé composée sur (last_name,first_name)
et une requête comme vous le mentionnez
WHERE first_name LIKE 'joh%'
... Il n'utilisera pas du tout l'index. Il effectuera une analyse de table. En raison de l'absence de
- une seule clé de colonne sur
first_name
- une clé composée avec
first_name
le plus à gauche
Alors scan de table nous voilà.
Veuillez consulter la page du manuel Index multi-colonnes pour en savoir plus. Et concentrez-vous sur le left-most
concept de celui-ci. En fait, allez sur cette page et recherchez le mot left
.
Voir la page du manuel sur Explain installation dans mysql. Aussi l'article Utilisation d'Explain pour écrire de meilleures requêtes Mysql .
Modifier
Il y a eu quelques modifications à la question depuis que je suis ici il y a une heure ou deux. Je vous laisse avec ce qui suit. Exécutez votre requête réelle via expliquer et déchiffrez via le Using Explain ...
lien ci-dessus ou une autre référence
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
affiche les nombres vaudou pour les rows
. Vaudou? Oui, car une requête qui durera potentiellement une heure, vous demandez explain
pour vous donner un compte flou, ne pas l'exécuter, et vous donner cette réponse en 2 secondes ou moins. Ne les considérez pas comme des nombres réels de critères lorsqu'ils sont exécutés pour de vrai, sans 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 |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+