Uma pergunta semelhante foi feita antes
Implicações de desempenho dos tamanhos MySQL VARCHAR
Aqui está o trecho da minha resposta
Você deve perceber as vantagens e desvantagens de usar CHAR vs VARCHAR
Com os campos CHAR, o que você aloca é exatamente o que recebe. Por exemplo, CHAR (15) aloca e armazena 15 bytes, independentemente de como você coloca os caracteres no campo. A manipulação de strings é simples e direta, pois o tamanho do campo de dados é totalmente previsível.
Com os campos VARCHAR, você obtém uma história completamente diferente. Por exemplo, o VARCHAR (15) na verdade aloca dinamicamente até 16 bytes, até 15 para dados e, pelo menos, 1 byte adicional para armazenar o comprimento dos dados. Se você tiver a string 'hello' para armazenar que terá 6 bytes, não 5. A manipulação da string sempre deve executar alguma forma de verificação de comprimento em todos os casos.
A troca é mais evidente quando você faz duas coisas: 1. Armazenando milhões ou bilhões de linhas 2. Colunas de indexação que são CHAR ou VARCHAR
TRADEOFF # 1 Obviamente, o VARCHAR possui a vantagem, já que dados de comprimento variável produziriam linhas menores e, portanto, arquivos físicos menores.
TRADEOFF # 2 Como os campos CHAR exigem menos manipulação de sequência devido às larguras fixas, as pesquisas de índice no campo CHAR são, em média, 20% mais rápidas que as dos campos VARCHAR. Esta não é nenhuma conjectura da minha parte. O livro MySQL Database Design and Tuning executou algo maravilhoso em uma tabela MyISAM para provar isso. O exemplo no livro fez algo como o seguinte:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Esta diretiva força todos os VARCHARs a se comportarem como CHARs. Eu fiz isso no meu trabalho anterior em 2007 e peguei uma tabela de 300 GB e acelerou as pesquisas de índice em 20%, sem alterar mais nada. Funcionou como publicado. No entanto, produziu uma tabela com quase o dobro de tamanho, mas isso simplesmente remonta ao tradeoff # 1.
Você pode analisar os dados armazenados para ver o que o MySQL recomenda para a definição de colunas. Basta executar o seguinte em qualquer tabela:
SELECT * FROM tblname PROCEDURE ANALYSE();
Isso percorrerá a tabela inteira e recomendará definições de coluna para cada coluna com base nos dados que ela contém, nos valores mínimos de campo, no máximo e em outros itens. Às vezes, você só precisa usar o bom senso ao planejar CHAR vs VARCHAR. Aqui está um bom exemplo:
Se você estiver armazenando endereços IP, a máscara para essa coluna terá no máximo 15 caracteres (xxx.xxx.xxx.xxx). Eu pularia imediatamente, CHAR(15)
porque os comprimentos dos endereços IP não variariam muito e a complexidade adicional da manipulação de strings controlada por um byte adicional. Você ainda pode fazer um PROCEDURE ANALYSE()
contra essa coluna. Pode até recomendar o VARCHAR. Meu dinheiro ainda estaria em CHAR sobre VARCHAR nesse caso.
Os problemas CHAR x VARCHAR podem ser resolvidos apenas através do planejamento adequado. Com grande poder vem uma grande responsabilidade (clichê, mas é verdade).
ATUALIZAR
Quando se trata do MD5, o cálculo strlen
interno deve ser eliminado ao alternar todo o formato da linha. Não seria necessário alterar a definição do campo.
Se a chave MD5 for o único VARCHAR presente, eu a utilizaria e converteria o formato da linha da tabela em fixo . Se houver um número significativo de outros campos VARCHAR presentes, eles também serão beneficiados. Em troca, a tabela seria expandida para aproximadamente o dobro do seu tamanho. Mas as consultas devem acelerar cerca de 20% a mais sem ajuste adicional.