¿Existe una diferencia de rendimiento en MySQL entre los tamaños varchar? Por ejemplo, varchar(25)
y varchar(64000)
. Si no es así, ¿hay alguna razón para no declarar todos los varchars con el tamaño máximo solo para garantizar que no se quede sin espacio?
45
Respuestas:
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
COMERCIO # 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.
COMERCIO # 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:
Esta directiva obliga a 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 columna. Simplemente ejecute lo siguiente en cualquier tabla:
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). Saltaría directamente a CHAR (15) en un abrir y cerrar de ojos porque las longitudes de las direcciones IP no variarán demasiado y la complejidad adicional de la manipulación de cadenas controlada por un byte adicional. Todavía podría hacer un ANÁLISIS DE PROCEDIMIENTO () contra dicha 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 gran poder viene una gran responsabilidad (cliché pero cierto)
fuente
La respuesta a esto es en realidad bastante compleja. La versión corta: hay una diferencia .
Al crear tablas temporales para filtrar resultados (por ejemplo,
GROUP BY
declaraciones), se asignará la longitud completa.El protocolo de conexión (que envía filas al cliente) probablemente asignará la longitud más grande.
El motor de almacenamiento puede / no puede implementar un varchar adecuado.
Para (2) admito que el protocolo de conexión no es algo con lo que estoy íntimamente familiarizado, pero el consejo general aquí es intentar y aplicar al menos un mínimo esfuerzo para adivinar la longitud.
fuente
La mayoría de las respuestas en este hilo tienen 5 años, escritas antes de que InnoDB y utf8 fueran valores predeterminados. Entonces, déjame comenzar de nuevo ...
Cuando una consulta necesita una tabla temporal interna, intenta usar una
MEMORY
tabla. Pero MEMORY no se puede usar siTEXT
/BLOB
columnas que se obtienen, ni siquieraTINYTEXT
.VARCHAR
mayor que alguna cantidad, probablemente 512 en la versión actual.Además, tenga en cuenta que
VARCHARs
se convierten enCHARs
. Entonces,VARCHAR(255)
con un seCHARACTER SET utf8
expande a 765 bytes, independientemente de lo que esté en la columna. Entonces, esto podría activarse:MEMORY
tabla se hace más grande que cualquieramax_heap_table_size
otmp_table_size
, que se convertirá en MyISAM y potencialmente derrame en el disco.Por lo tanto,
VARCHAR(25)
es más probable que se quedeMEMORY
, por lo tanto, sea más rápido.(255)
No es tan bueno y(64000)
es malo.(En el futuro, las tablas temporales probablemente lo serán
InnoDB
, y parte de esta respuesta deberá revisarse).fuente
Una columna varchar de ese tamaño hace que las consultas en toda la tabla sean más propensas a usar tablas temporales. De acuerdo con el libro MySQL de alto rendimiento. Cuando el optimizador intenta ver si puede ejecutar esta consulta en la memoria o si necesita una tabla temporal, observa el tamaño de la fila en función de la definición de la tabla, es decir, en cuanto a la velocidad, no intenta ver cuántos caracteres de 64K en realidad estás usando Esta es la razón por la cual los escritores recomiendan que no extienda esa definición más allá de los posibles valores reales que irían en la columna. Obviamente, si se prepara para más consultas en las tablas temporales (incluso si el tamaño real de los datos podría caber en la RAM), ahora ha incurrido en penalizaciones de E / S que podría haber evitado.
fuente
Entiendo que los campos más pequeños pueden incluirse directamente en el índice, mientras que los campos más largos no pueden. Debido a esa limitación, si desea que las cadenas sean indexables, diría que las mantenga más cortas. De lo contrario, no, dado que ambos son varchar, las operaciones como ordenar o comparar funcionarán en el mismo tiempo, ya sea que los campos sean 25 o MAX.
fuente
Esta frase implica que hace la pregunta porque no está seguro acerca de los datos que almacenará en la base de datos. Si eso es cierto, será de gran utilidad averiguarlo lo antes posible, porque lo necesitará para planificar la capacidad. Si puede obtener elementos de datos con 7000 caracteres, por ejemplo, debe saberlo porque eso tendría implicaciones de rendimiento en cualquier DBMS.
Dicho esto, prefiero tener tamaños de columna relacionados con el contenido esperado. Por ejemplo, es poco probable que un número de teléfono tenga más de 50 caracteres, incluso si incluye un código de país y una extensión. Del mismo modo, un código postal o postal tendrá 20 caracteres o menos.
fuente