number - mysql vs sql server performance
Importancia de la longitud varchar en la tabla MySQL (10)
¿Actuación? No. Almacenamiento en disco? Sí, pero es barato y abundante. A menos que su base de datos crezca hasta una escala de terabytes, probablemente esté bien.
Tengo una tabla MySQL donde las filas se insertan dinámicamente. Como no puedo estar seguro de la longitud de las cadenas y no las quiero cortadas, las hago varchar (200), que generalmente es mucho más grande de lo que necesito. ¿Hay un gran rendimiento al dar un campo varchar mucho más largo de lo necesario?
Algunos de ustedes se equivocan al pensar que un varchar(200)
ocupa más tamaño de tabla en el disco que un varchar(20)
. Este no es el caso. Solo cuando se supera 255 caracteres, mysql usa un byte adicional para determinar la longitud de los datos de campo varchar
.
Debería intentar ver una columna varchar de la misma manera que lo haría con una columna char en la mayoría de los escenarios y establecer la longitud de forma conservadora. No siempre debe pensar en el modificador de var sino en algo que afecte su toma de decisiones en la longitud máxima. En realidad, debería verse como una sugerencia de rendimiento en el sentido de que las cadenas suministradas serán de diferentes longitudes.
No es una directiva que debe ser estrictamente seguida por las partes internas de la base de datos, puede ignorarse por completo. Tenga cuidado con esto, sin embargo, como a veces la implementación puede tener fugas (longitud fija y relleno, por ejemplo), aunque no debería en un mundo ideal.
Si tiene un varchar (255), entonces no tiene garantía de que el rendimiento siempre se comporte de manera diferente a un char (255) en cualquier circunstancia.
Puede parecer fácil configurarlo en algo como 255, 65535, etc. en línea con los consejos dados en el manual sobre los requisitos de almacenamiento. Esto da la impresión de que cualquier valor entre 0 (sí, es una cosa) y 255 tendrá el mismo impacto. Sin embargo, eso no es algo que pueda garantizarse por completo.
Los requisitos de almacenamiento tienden a ser ciertos o un buen indicador para los motores de almacenamiento persistentes decentes y maduros en términos de almacenamiento en filas. No es un indicador tan fuerte para cosas como los índices.
A veces es una pregunta difícil, exactamente cuánto tiempo debe ser un trozo de cuerda para configurarlo hasta el límite más alto que usted sabe que debería estar dentro, pero eso no tiene ningún impacto. Desafortunadamente, esto es a menudo algo que el usuario debe resolver y en realidad es algo arbitrario. Realmente no se puede decir que nunca se sobredimensione una cadena porque hay casos en los que no está exactamente seguro.
Debe asegurarse de que las consultas MySQL generen un error cuando una cadena es demasiado larga en lugar de truncada, para que al menos sepa si es posible que sea demasiado corta debido a las emisiones de errores. Cambiar el tamaño de las columnas para agrandarlas o reducirlas puede ser una costosa operación DDL, esto debe tenerse en cuenta.
El juego de caracteres también debe considerarse cuando entran en juego la duración y el rendimiento. La longitud se refiere a esto en lugar de bytes. Si usa utf8 por ejemplo, (no MB4) entonces varchar (255) es realmente varbinary (3 * 255). Es difícil saber cómo cosas así realmente se desarrollarán sin ejecutar pruebas y analizar profundamente el código fuente y la documentación. Debido a esto, existe la posibilidad de que una longitud excesiva tenga un impacto inesperadamente inflado. esto no solo se aplica al rendimiento. Si algún día necesitas cambiar el conjunto de caracteres de una columna de varchar a uno más grande, entonces podrías terminar golpeando un límite sin ningún recurso si permites que haya cadenas innecesariamente largas que podrían haberse evitado. Esto normalmente es un problema de nicho, pero surge, recientemente fue un problema significativo con la introducción de utf8mb4 para MySQL e índices que tienen un límite en la longitud de la clave.
Si resulta que MAX (LENGTH (columna)) es siempre <64 (como si se hubiera decidido que habría un límite en la entrada que no coincidía con la definición de la columna) pero tiene varchar (255), entonces hay una Es muy probable que use cuatro veces más espacio de lo necesario en algunos escenarios.
Esto podría incluir:
- Diferentes motores, algunos pueden ignorarlo por completo.
- Los tamaños de búfer, por ejemplo, actualización o inserción, pueden tener que asignar el total de 255 (aunque no he verificado el código fuente para probar esto, solo es una hipótesis).
- Índices, esto será inmediatamente obvio si intenta hacer una clave compuesta a partir de muchas columnas varchar (255).
- Tablas intermedias y posiblemente conjuntos de resultados. Dada la forma en que funcionan las transacciones, puede que no siempre sea posible que algo use la longitud máxima real de las cadenas en una columna en lugar del límite definido.
- Las optimizaciones predictivas internas pueden tomar la longitud máxima como una entrada.
- Cambios en las versiones de implementación de la base de datos
Como regla general, en realidad no es necesario que varchar sea más largo de lo que debe ser de todos modos, problemas de rendimiento o no, así que le recomiendo que lo haga cuando pueda. Tomar más esfuerzo para muestrear el tamaño de sus datos, imponer un límite verdadero o descubrir el verdadero límite a través de preguntar / investigar es el enfoque ideal.
Cuando no puedes, si quieres hacer algo como varchar (255) para los casos en los que tienes dudas, te recomiendo que hagas la ciencia. Esto podría consistir en duplicar la tabla, reducir el tamaño de la columna var char y luego copiar los datos en ella desde el original y observar el tamaño de los datos del índice / fila (indexar también la columna, también probarla como clave principal que podría comportarse de manera diferente en InnoDB ya que las filas están ordenadas por la clave principal). Por lo menos, de esta forma sabrá si tiene un impacto en IO, que tiende a ser uno de los cuellos de botella más sensibles. Probar el uso de la memoria es más difícil, es difícil probarlo exhaustivamente. Recomendaría probar los peores casos potenciales (consultas con muchos intermedios en los resultados de la memoria, verificar con explicación para tablas temporales grandes, etc.).
Si sabe que no habrá muchas filas en la tabla, no va a utilizar la columna para uniones, índices (especialmente compuestos, únicos), etc. entonces lo más probable es que no tenga muchos problemas.
El tamaño es el rendimiento! Cuanto menor es el tamaño, mejor. No hoy o mañana, pero algún día sus mesas crecerán hasta alcanzar un tamaño en lo que respecta a serios cuellos de botella, sin importar el diseño que haya diseñado. Pero puede prever algunos de los potenciales cuellos de botella en su fase de diseño que es probable que sucedan primero y tratar de ampliar el tiempo que su DB funcionará rápida y felizmente hasta que necesite replantear su esquema o escalar horizontalmente agregando más servidores.
En su caso, hay muchas pérdidas de rendimiento que puede encontrar: las uniones grandes son casi imposibles con columnas varchar
largas. La indexación en esas columnas es un verdadero asesino. Tu disco tiene que almacenar los datos. Una página de memoria puede contener menos filas y los escaneos de tabla serán mucho más lentos. Además, es poco probable que la caché de consultas lo ayude aquí.
Tienes que preguntarte: ¿Cuántas plaquitas por año pueden pasar? ¿Cuál es la duración promedio? ¿Realmente necesito más de 200 caracteres o puedo detectarlo en mi interfaz de aplicaciones, incluso informando a los usuarios sobre la longitud máxima? ¿Puedo dividir la tabla en una tabla estrecha para indexar y escanear rápidamente y otra para almacenar datos adicionales de menor tamaño que se necesitan con menor frecuencia? ¿Puedo escribir los posibles datos varchar en categorías y así extraer algunos de los datos en unas pocas columnas más pequeñas, quizás int o bool, y reducir la columna varchar de esa manera?
Puedes hacer mucho aquí. Puede ser mejor ir con una primera suposición y luego rediseñar paso a paso usando datos de rendimiento medidos en la vida real. Buena suerte.
Hay un posible impacto en el rendimiento: en MySQL, las tablas temporales y las tablas de MEMORY
almacenan una columna VARCHAR
como una columna de longitud fija, acolchada a su longitud máxima. Si diseña columnas VARCHAR
mucho más grandes que el tamaño más grande que necesita, consumirá más memoria de la que necesita. Esto afecta la eficiencia de la memoria caché, la velocidad de clasificación, etc.
No, en el sentido de que si los valores que está almacenando en esa columna son siempre (digamos) de menos de 50 caracteres, declarar la columna como varchar(50)
o varchar(200)
tiene el mismo rendimiento.
Puede haber éxitos de rendimiento, pero generalmente no en un nivel que la mayoría de los usuarios notarían.
Cuando el tamaño de cada campo se conoce de antemano, MySQL sabe exactamente cuántos bytes hay entre cada campo / fila y puede avanzar la página sin leer todos los datos. El uso de caracteres variables minimiza esta capacidad de optimización.
¿El varchar resulta en un golpe de rendimiento debido a la fragmentación de datos?
Aún mejor, char vs varchar .
Para la mayoría de los usos, estará bien con cualquiera de los dos, pero hay una diferencia, y para las bases de datos a gran escala, hay razones por las que elegiría una u otra.
Siendo varchar, en lugar de solo char, el tamaño se basa en un campo interno para indicar su longitud real y la cadena misma. Entonces, usar varchar (200) no es muy diferente de usar varchar (150), excepto que tienes el potencial de almacenar más.
Y debe considerar lo que sucede en una actualización, cuando crece una fila. Pero si esto es raro, entonces deberías estar bien.
VARCHAR es ideal para la situación que describes, porque representa el "carácter variable": el límite, basado en tu ejemplo, sería de 200 caracteres, pero se acepta cualquier cantidad menor y no se completará el tamaño asignado de la columna.
VARCHAR también ocupa menos espacio: los valores se almacenan como un prefijo de un byte o de dos bytes más los datos. El prefijo de longitud indica la cantidad de bytes en el valor. Una columna utiliza un byte de longitud si los valores no requieren más de 255 bytes, dos bytes de longitud si los valores pueden requerir más de 255 bytes.
Para obtener más información sobre la comparación de los tipos de datos CHAR de MySQL a VARCHAR, consulte este enlace .
según el nombre del tipo de datos, sugiere que esto es VARCHAR, es decir, el almacenamiento de datos de caracteres variables, el propio motor mysql asigna la memoria que se utiliza de acuerdo con los datos almacenados, por lo que no hay impacto en el rendimiento según mi conocimiento.