Aqui está um trecho da saída da ferramenta Percona pt-duplicate-key-checker
que procura por índices redundantes:
# Key myidx ends with a prefix of the clustered index
# Key definitions:
# KEY `myidx` (`bar`,`foo`)
# PRIMARY KEY (`foo`),
# Column types:
# `bar` mediumint(8) unsigned not null default '0'
# `foo` mediumint(8) unsigned not null auto_increment
# To shorten this duplicate clustered index, execute:
ALTER TABLE `mydb`.`mytable` DROP INDEX `myidx`, ADD INDEX `myidx` (`bar`);
Por que a ferramenta sugere isso? O índice composto original não pode ser útil?
Pelo que entendi, um índice em bar
valeria a pena ser apagado dado um PK (bar,foo)
, mas não é o caso aqui.
A chave primária é uma parte de qualquer chave secundária no InnoDB.
Discordo da análise dada pela ferramenta.
Quando vejo
INDEX(bar, foo)
, suponho que haja alguma consulta que precise que essas duas colunas, nessa ordem, estejam nesse índice composto.O fato de
foo
ser o PK, eINDEX(bar)
ser idêntico ao índice acima é irrelevante.Quando vejo apenas
INDEX(bar)
, suponho que há alguma consulta que precisa(bar)
semid
.Quando eu vir os dois, direi que o mais curto é 'redundante' e recomendo removê-lo.
Além disso, "Para encurtar este índice clusterizado duplicado" está errado .
INDEX(bar)
não é 'mais curto' do queINDEX(bar, foo)
. E não é um "índice clusterizado. Apenas o PK é "clusterizado".Se fosse
UNIQUE(bar, foo)
, então eu recomendaria mudarUNIQUE
paraINDEX
. Isso é para queINSERTs
não seja necessário fazer uma verificação de exclusividade desnecessária.Vamos criar uma tabela simples e ver o que o MySQL (5.7.20 MySQL Community Server) tem a nos dizer:
Aqui está uma consulta simples que pode ser lida a partir do índice:
Isso mostra que a barra de teclas é usada e tem 2 partes de chave, ambas sendo lidas para produzir um comprimento de chave de 8 (2x4). Agora vamos mudar a chave composta para um único campo e verificar novamente:
Apenas as partes principais e o comprimento agora mudam, o que é esperado, mas ainda é uma leitura de índice. Se transformarmos isso em uma consulta de intervalo no campo PK com uma restrição no campo indexado, vamos ver o que acontece:
O planejador de consulta considerou o PK para a consulta, mas escolheu o índice para
bar
, que agora tem uma mudança interessante em relação ao índice anterior lido, pois podemos ver que agora ele mostra como 2 partes principais novamente e um comprimento de 8:Isso nos diz que o MySQL acessou o PK que está automaticamente contido no índice secundário