Se hizo una pregunta similar antes
Implicaciones de rendimiento de los tamaños de MySQL VARCHAR
Aquí está el extracto de mi respuesta.
Debe darse cuenta de las ventajas de usar CHAR vs VARCHAR
Con los campos CHAR, lo que asigna es exactamente lo que obtiene. Por ejemplo, CHAR (15) asigna y almacena 15 bytes, sin importar la cantidad de caracteres que coloque en el campo. La manipulación de cadenas es simple y directa ya que el tamaño del campo de datos es totalmente predecible.
Con los campos VARCHAR, obtienes una historia completamente diferente. Por ejemplo, VARCHAR (15) en realidad asigna dinámicamente hasta 16 bytes, hasta 15 para datos y, al menos, 1 byte adicional para almacenar la longitud de los datos. Si tiene la cadena 'hola' para almacenar que tomará 6 bytes, no 5. La manipulación de cadenas siempre debe realizar alguna forma de verificación de longitud en todos los casos.
La compensación es más evidente cuando haces dos cosas: 1. Almacenamiento de millones o miles de millones de filas 2. Columnas de indexación que son CHAR o VARCHAR
TRADEOFF # 1 Obviamente, VARCHAR tiene la ventaja ya que los datos de longitud variable producirían filas más pequeñas y, por lo tanto, archivos físicos más pequeños.
TRADEOFF # 2 Dado que los campos CHAR requieren menos manipulación de cadenas debido a los anchos de campo fijos, las búsquedas de índice contra el campo CHAR son en promedio un 20% más rápidas que las de los campos VARCHAR. Esta no es ninguna conjetura de mi parte. El libro MySQL Database Design and Tuning realizó algo maravilloso en una tabla MyISAM para probar esto. El ejemplo en el libro hizo algo como lo siguiente:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Esta directiva obliga a todos los VARCHAR a comportarse como CHAR. Hice esto en mi trabajo anterior en 2007 y tomé una tabla de 300GB y aceleré las búsquedas de índice en un 20%, sin cambiar nada más. Funcionó según lo publicado. Sin embargo, produjo una tabla de casi el doble de tamaño, pero eso simplemente se remonta a la compensación # 1.
Puede analizar los datos que se almacenan para ver qué recomienda MySQL para la definición de columnas. Simplemente ejecute lo siguiente en cualquier tabla:
SELECT * FROM tblname PROCEDURE ANALYSE();
Esto atravesará toda la tabla y recomendará definiciones de columna para cada columna en función de los datos que contiene, los valores mínimos de campo, los valores máximos de campo, etc. A veces, solo tiene que usar el sentido común al planificar CHAR vs VARCHAR. Aquí hay un buen ejemplo:
Si está almacenando direcciones IP, la máscara para dicha columna tiene como máximo 15 caracteres (xxx.xxx.xxx.xxx). Me gustaría saltar CHAR(15)
en un abrir y cerrar de ojos porque las longitudes de las direcciones IP no variarán mucho y la complejidad adicional de la manipulación de cadenas controlada por un byte adicional. Todavía podrías hacer una PROCEDURE ANALYSE()
contra tal columna. Incluso puede recomendar VARCHAR. Mi dinero todavía estaría en CHAR sobre VARCHAR en este caso.
Los problemas de CHAR vs VARCHAR solo se pueden resolver mediante una planificación adecuada. Con un gran poder viene una gran responsabilidad (cliché pero cierto).
ACTUALIZAR
Cuando se trata de MD5, el cálculo de strlen
internamente debe eliminarse al cambiar todo el formato de fila. No habría necesidad de cambiar la definición del campo.
Si la clave MD5 es el único VARCHAR presente, lo buscaría y convertiría el formato de fila de la tabla a fijo . Si hay un número significativo de otros campos VARCHAR presentes, también se beneficiarían. A cambio, la tabla se expandiría a aproximadamente el doble de su tamaño. Pero las consultas deberían acelerar un 20% más sin ajustes adicionales.