length generate mysql performance innodb sequence uuid

mysql generate uuid length



¿Desempeño de UUID en MySQL? (8)

¿Qué tal un UID hecho a mano? Asigne a cada uno de los miles de servidores una ID y convierta la clave principal en una clave combinada de autoincrement, MachineID ???

Estamos considerando usar valores de UUID como claves principales para nuestra base de datos MySQL. Los datos que se insertan se generan a partir de docenas, cientos o incluso miles de computadoras remotas y se insertan a una velocidad de 100 a 40,000 inserciones por segundo, y nunca haremos ninguna actualización.

La base de datos en sí misma llegará a alrededor de 50 millones de registros antes de que comencemos a recolectar datos, por lo que no es una base de datos masiva, pero tampoco pequeña. También estamos planeando ejecutar InnoDB, aunque estamos abiertos a cambiar eso si hay un mejor motor para lo que estamos haciendo.

Estábamos listos para usar el UUID Tipo 4 de Java, pero en las pruebas hemos observado un comportamiento extraño. Por un lado, estamos almacenando como varchar (36) y ahora me doy cuenta de que sería mejor usar el binario (16), aunque estoy mucho mejor sin estar seguro.

La pregunta más importante es: ¿qué tan mal esta información aleatoria arruinar el índice cuando tenemos 50 millones de registros? ¿Estaríamos mejor si usáramos, por ejemplo, un UUID de tipo 1 donde los bits más a la izquierda tenían marca de tiempo? ¿O tal vez deberíamos deshacernos de los UUID por completo y considerar las claves primarias de auto_increment?

Estoy buscando ideas / consejos generales sobre el rendimiento de diferentes tipos de UUID cuando se almacenan como una clave de índice / primaria en MySQL. ¡Gracias!


Algo a tener en cuenta es que los Aumentos automáticos se generan de uno en uno y no se pueden resolver con una solución paralela. La lucha por usar UUID eventualmente se reduce a lo que quieres lograr versus lo que potencialmente sacrificas.

En rendimiento, briefly :

Un UUID como el anterior tiene 36 caracteres, incluidos los guiones. Si almacena este VARCHAR (36), disminuirá dramáticamente el rendimiento de comparación. Esta es su clave principal, no desea que sea lenta.

En su nivel de bit, un UUID es de 128 bits, lo que significa que cabe en 16 bytes, tenga en cuenta que no es muy legible, pero mantendrá el almacenamiento bajo, y es solo 4 veces más grande que un int de 32 bits o 2 veces más grande que un int de 64 bits. Usaré un VARBINARIO (16) Teóricamente, esto puede funcionar sin demasiados gastos.

Recomiendo leer las siguientes dos publicaciones:

Creo que entre los dos, ellos responden tu pregunta.


Asignaría a cada servidor una identificación numérica de forma transaccional. Luego, cada registro insertado simplemente autoincrementará su propio contador. La combinación de ServerID y RecordID será única. El campo ServerID se puede indexar y el rendimiento de selección futura basado en ServerID (si es necesario) puede ser mucho mejor.


Como la clave primaria se genera de forma descentralizada, no tiene la opción de usar un auto_increment de todos modos.

Si no tiene que ocultar la identidad de las máquinas remotas, use UUID tipo 1 en lugar de UUID. Son más fáciles de generar y al menos no perjudican el rendimiento de la base de datos.

Lo mismo ocurre con varchar (char, really) vs. binary: solo puede ayudar. ¿Es realmente importante, cuánto mejora el rendimiento?


En lugar de generar centralmente claves únicas para cada inserción, ¿qué hay de asignar bloques de claves a servidores individuales? Cuando se queden sin llaves, pueden solicitar un nuevo bloque. Luego, resuelve el problema de la sobrecarga conectándose a cada inserción.

Keyserver mantiene la próxima identificación disponible

  • El servidor 1 solicita el bloque de identificación.
  • Keyserver regresa (1,1000)
    El servidor 1 puede insertar 1000 registros hasta que necesite solicitar un nuevo bloque
  • El servidor 2 solicita el bloque de índice.
  • Keyserver regresa (1001,2000)
  • etc ...

Podría proponer una versión más sofisticada en la que un servidor podría solicitar el número de claves necesarias o devolver los bloques no utilizados al servidor de claves, lo que por supuesto necesitaría mantener un mapa de bloques usados ​​/ no utilizados.


En mi trabajo, usamos UUID como PK. Lo que puedo decirles por experiencia es NO USARLOS como PK (SQL Server por cierto).

Es una de esas cosas que cuando tienes menos de 1000 registros, está bien, pero cuando tienes millones, es lo peor que puedes hacer. ¿Por qué? Debido a que los UUID no son secuenciales, cada vez que se inserta un nuevo registro, MSSQL necesita ir a la página correcta para insertar el registro y luego insertar el registro. La consecuencia realmente desagradable de esto es que las páginas terminan en diferentes tamaños y terminan fragmentadas, por lo que ahora tenemos que hacer una desfragmentación periódica.

Cuando utiliza una autoincrementación, MSSQL siempre irá a la última página y terminará con páginas de igual tamaño (en teoría), por lo que el rendimiento para seleccionar esos registros es mucho mejor (también porque los INSERT no bloquearán la tabla / página para hasta la vista).

Sin embargo, la gran ventaja de usar UUID como PKs es que si tenemos grupos de bases de datos, no habrá conflictos cuando se fusionen.

Recomendaría el siguiente modelo: 1. PK INT Identity 2. Columna adicional generada automáticamente como UUID.

De esta forma, el proceso de fusión es posible (UUID sería su clave REAL, mientras que el PK sería algo temporal que le da un buen rendimiento).

NOTA: Que la mejor solución es usar NEWSEQUENTIALID (como estaba diciendo en los comentarios), pero para la aplicación heredada que no tiene mucho tiempo para refactorizar (y, lo que es peor, no controla todas las inserciones), no es posible hacerlo. Pero de hecho, a partir de 2017, diría que la mejor solución es NEWSEQUENTIALID o Guid.Comb con NHibernate.

Espero que esto ayude


Tiendo a evitar UUID simplemente porque es un dolor almacenar y un dolor de usar como clave principal, pero hay ventajas. El principal es que son ÚNICOS.

Por lo general, resuelvo el problema y evito el UUID utilizando campos clave dobles.

COLECTOR = ÚNICO ASIGNADO A UNA MÁQUINA

ID = REGISTRO RECOGIDO POR EL COLECTOR (campo auto_inc)

Esto me ofrece dos cosas. La velocidad de los campos autoinc. Y la exclusividad de los datos que se almacenan en una ubicación central después de que se recopilen y agrupen. También sé mientras navego por los datos en los que se recopiló, lo que a menudo es bastante importante para mis necesidades.

He visto muchos casos al tratar con otros conjuntos de datos para clientes en los que decidieron usar UUID, pero todavía tienen un campo para el lugar donde se recopilaron los datos, que realmente es una pérdida de esfuerzo. Simplemente usando dos (o más si es necesario) campos como su clave realmente ayuda.

Acabo de ver demasiados éxitos de rendimiento con UUID. Se sienten como un tramposo ...


Un UUID es una identificación universal única. Es la parte universal que deberías considerar aquí.

¿ Realmente necesita que los ID sean universalmente únicos? Si es así, entonces los UUID pueden ser su única opción.

Le sugiero encarecidamente que si usa UUID, los almacene como un número y no como una cadena. Si tiene más de 50 millones de registros, el ahorro en espacio de almacenamiento mejorará su rendimiento (aunque no podría decir por cuánto).

Si sus ID no necesitan ser universalmente únicos, entonces no creo que pueda hacer mucho mejor que usar auto_increment, que garantiza que los ID serán únicos dentro de una tabla (ya que el valor aumentará cada vez)