Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

O curinga na coluna mais à esquerda do índice composto significa que as colunas restantes no índice não são usadas na pesquisa de índice (MySQL)?


Aqui estão suas perguntas. Plural. Ao reformulá-las (com "em outras palavras"), elas são apenas perguntas diferentes. Fazer isso não torna necessariamente mais fácil para os respondentes. Pelo contrário.

Q1:[Title question] O curinga na coluna mais à esquerda do índice composto significa que as colunas restantes no índice não são usadas na pesquisa de índice (MySQL)?

A1:Não, não significa isso.

Q2:O curinga usado na condição last_name significa que a condição first_name não será usada para ajudar o MySQL a encontrar índices?

A2:Não, não significa isso. Além disso, a cauda dessa pergunta é ambígua. Ele já sabe qual Index usar pode ser uma resposta a tal imprecisão.

Q3:Em outras palavras, colocando um curinga na condição last_name, o MySQL fará apenas uma pesquisa de índice parcial (e ignora as condições fornecidas nas colunas que estão à direita de last_name)?

R3:Não. As colunas mais à direita são servidas a partir do índice de forma semelhante a uma estratégia de índice de cobertura que se beneficia da lentidão da pesquisa da página de dados.

Q4:...o Exemplo-1 seria mais rápido que o Exemplo-2?

A4:Sim. É um índice de cobertura em relação a essas colunas. Consulte índices de cobertura.

Como um aparte sobre Q4. É irrelevante se é um PK ou não PK. Há provavelmente uma dúzia de razões pelas quais isso como um PK seria terrível para seu aplicativo.

Resposta(s) original(is) abaixo:

com somente uma chave composta em (last_name,first_name) e uma consulta como você menciona
WHERE first_name LIKE 'joh%'

... Ele não usará o índice. Ele fará uma varredura de tabela. Devido à ausência de
  • uma chave de coluna única em first_name
  • uma chave composta com first_name mais à esquerda

Então, digitalização de mesa, aqui vamos nós.

Consulte a página do manual Índices de várias colunas para ler mais. E concentre-se no left-most conceito disso. Na verdade, vá para essa página e pesquise a palavra left .

Consulte a página do manual no Explicar facilidade no mysql. Também o artigo Usando o Explain para escrever consultas MySQL melhores .

Editar


Houve algumas edições na pergunta desde que estive aqui uma ou duas horas atrás. Deixo-vos com o seguinte. Execute sua consulta real por meio de explicação e decifre por meio do Using Explain ... link acima ou outra referência
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 renderiza números voodoo para rows . Vodu? Sim, porque uma consulta que potencialmente será executada por uma hora, você está pedindo explain para lhe dar uma contagem difusa, não executá-la, e dar-lhe essa resposta em 2 segundos ou menos. Não considere isso como contagem real #'s para critérios quando for executado de verdade, sem 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 |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+