Existe uma diferença de desempenho no MySQL entre tamanhos de varchar? Por exemplo, varchar(25)
e varchar(64000)
. Caso contrário, existe um motivo para não declarar todos os varchars com o tamanho máximo apenas para garantir que você não fique sem espaço?
45
Respostas:
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 requerem 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:
Essa diretiva força 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 que estão sendo armazenados para ver o que o MySQL recomenda para a definição de colunas. Basta executar o seguinte em qualquer tabela:
Isso percorrerá a tabela inteira e recomendará definições de coluna para todas as colunas com base nos dados que ela contém, nos valores mínimos de campo, no máximo e assim por diante. À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 direto no CHAR (15) em um piscar de olhos, 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 uma ANÁLISE DE PROCEDIMENTO () nessa coluna. Pode até recomendar 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 grande responsabilidade (clichê, mas é verdade)
fonte
A resposta para isso é realmente bastante complexa. A versão curta: há uma diferença .
Ao criar tabelas temporárias para filtrar resultados (por exemplo,
GROUP BY
instruções), o comprimento total será alocado.O protocolo de conexão (enviando linhas para o cliente) provavelmente alocará o comprimento maior.
O mecanismo de armazenamento pode / pode não implementar um varchar adequado.
Pois (2) admito que o protocolo de ligação não seja algo com o qual estou intimamente familiarizado, mas o conselho geral aqui é tentar aplicar pelo menos algum esforço mínimo para adivinhar o comprimento.
fonte
A maioria das respostas neste tópico tem 5 anos, escritas antes do InnoDB e utf8 serem padrões. Então, deixe-me começar de novo ...
Quando uma consulta precisa de uma tabela temporária interna, ela tenta usar uma
MEMORY
tabela. Mas MEMORY não pode ser usado seTEXT
/BLOB
colunas sendo buscadas, nem mesmoTINYTEXT
.VARCHAR
maior que alguma quantia, provavelmente 512 na versão atual.Além disso, observe que
VARCHARs
são transformados emCHARs
. Portanto,VARCHAR(255)
com umCHARACTER SET utf8
expande para 765 bytes, independentemente do que está na coluna. Em seguida, isso pode ser acionado:MEMORY
tabela ficar maior que ummax_heap_table_size
ou outrotmp_table_size
, será convertida em MyISAM e potencialmente será derramada em disco.Portanto,
VARCHAR(25)
é mais provável que fiqueMEMORY
, portanto, seja mais rápido.(255)
não é tão bom e(64000)
é ruim.(No futuro, as tabelas temporárias provavelmente serão
InnoDB
, e parte dessa resposta precisará ser revisada.)fonte
Uma coluna varchar desse tamanho aumenta a probabilidade de consultas em toda a tabela usarem tabelas temporárias. De acordo com o livro MySQL de alto desempenho. Quando o otimizador tenta ver se pode executar esta consulta na memória ou se precisa de uma tabela temporária, ele analisa o tamanho da linha com base na definição da tabela, ou seja, para velocidade, ele não tenta ver quanto dos caracteres de 64 K você está realmente usando. É por isso que os escritores recomendam que você não estique essa definição muito além dos possíveis valores reais que poderiam aparecer na coluna. Obviamente, se você se preparar para mais consultas em tabelas temporárias (mesmo que o tamanho real dos dados possa caber na RAM), você terá agora multas de E / S que poderia ter evitado.
fonte
Entendo que os campos menores podem ser incluídos diretamente no índice, enquanto os mais longos não podem. Devido a essa limitação, se você deseja que as strings sejam indexáveis, eu diria que as mantenha menores. Caso contrário, não, sendo assim, como ambos são varchar, as operações, como classificação ou comparação, funcionarão no mesmo tempo, independentemente de os campos serem 25 ou MAX.
fonte
Essa frase implica que você faz a pergunta porque não tem certeza dos dados que estará armazenando no banco de dados. Se isso for verdade, você estará bem servido para descobrir o mais rápido possível, porque será necessário para o planejamento da capacidade. Se você pode obter elementos de dados com 7000 caracteres, por exemplo, é necessário saber porque isso teria implicações no desempenho de qualquer DBMS.
Dito isto, eu prefiro ter tamanhos de coluna relacionados ao conteúdo esperado. Por exemplo, é improvável que um número de telefone tenha mais de 50 caracteres, mesmo se você incluir um código e extensão de país. Da mesma forma, um CEP ou código postal provavelmente terá 20 caracteres ou menos.
fonte