Como @Devart diz, o comprimento total do seu índice é muito longo.
A resposta curta é que você não deveria indexar colunas VARCHAR tão longas, porque o índice será muito volumoso e ineficiente.
A melhor prática é usar índices de prefixo então você está indexando apenas uma substring esquerda dos dados. A maioria dos seus dados será muito menor que 255 caracteres de qualquer maneira.
Você pode declarar um comprimento de prefixo por coluna ao definir o índice. Por exemplo:
...
KEY `index` (`parent_menu_id`,`menu_link`(50),`plugin`(50),`alias`(50))
...
Mas qual é o melhor comprimento de prefixo para uma determinada coluna? Aqui está um método para descobrir:
SELECT
ROUND(SUM(LENGTH(`menu_link`)<10)*100/COUNT(`menu_link`),2) AS pct_length_10,
ROUND(SUM(LENGTH(`menu_link`)<20)*100/COUNT(`menu_link`),2) AS pct_length_20,
ROUND(SUM(LENGTH(`menu_link`)<50)*100/COUNT(`menu_link`),2) AS pct_length_50,
ROUND(SUM(LENGTH(`menu_link`)<100)*100/COUNT(`menu_link`),2) AS pct_length_100
FROM `pds_core_menu_items`;
Ele informa a proporção de linhas que não têm mais do que um determinado comprimento de string no
menu_link
coluna. Você pode ver uma saída como esta:+---------------+---------------+---------------+----------------+
| pct_length_10 | pct_length_20 | pct_length_50 | pct_length_100 |
+---------------+---------------+---------------+----------------+
| 21.78 | 80.20 | 100.00 | 100.00 |
+---------------+---------------+---------------+----------------+
Isso informa que 80% de suas strings têm menos de 20 caracteres e todas as suas strings têm menos de 50 caracteres. Portanto, não há necessidade de indexar mais do que um comprimento de prefixo de 50 e certamente não há necessidade de indexar o comprimento total de 255 caracteres.
PS:O
INT(1)
e INT(32)
tipos de dados indica outro mal-entendido sobre o MySQL. O argumento numérico não tem efeito relacionado ao armazenamento ou ao intervalo de valores permitidos para a coluna. INT
é sempre de 4 bytes e sempre permite valores de -2147483648 a 2147483647. O argumento numérico é sobre valores de preenchimento durante a exibição, o que não tem efeito a menos que você use o ZEROFILL
opção.