MySQL de alto rendimiento para muchos SELECT / INSERTs / UPDATEs / DELETEs

9

Estoy creando un módulo donde cada usuario a menudo obtiene un registro en una tabla durante 10 a 300 segundos.

Cuando expira el tiempo, se elimina un registro. El caso es: habrá muchos usuarios y los registros cambiarán con mucha frecuencia: ¿cómo afectará esto el rendimiento de la aplicación para esta tabla, porque los registros cambiarán con mucha frecuencia y me pregunto si mysql está bien con eso? Al igual que los índices iban y venían, los datos cambian como 200 veces / segundo para esta tabla en particular. Tal vez estoy eligiendo una mala solución para este tipo de trabajo. Alguna sugerencia ?

¡Gracias!

Aivaras
fuente
2
¿Has intentado almacenar datos en Memcache y luego vaciarlos en una transacción cada pocos segundos?
3
"los datos cambian como 200 veces / segundos para esta tabla en particular" Creo que la línea deletrea estos datos debe mantenerse en la memoria, la vida útil para la que debe persistir es pequeña, ¿entonces probablemente no debería ir al disco?
Los índices van y vienen? No se me ocurre ninguna razón por la que necesite crear y soltar índices con mucha frecuencia.
Barry Brown

Respuestas:

3

Una cosa que debe tenerse en cuenta es cómo MySQL usa buffers para sus principales motores de almacenamiento: InnoDB y MyISAM .

Lo que se encuentra en la memoria caché difiere mucho entre estos motores de almacenamiento.

InnoDB almacena en caché tanto las páginas de datos como las de índice. Se cargan en el InnoDB Buffer Pool, que es dimensionado por innodb_buffer_pool_size .

MyISAM almacena en caché solo las páginas de índice y se cargan en el Key Cache (Key Buffer), que tiene el tamaño key_buffer_size .

Debe usar information_schema.tables para obtener los tamaños de datos e índices ocupados en el disco para dimensionar correctamente el InnoDB Buffer Pool y MyISAM Key Cache .

Según la cantidad de datos que tenga y el tiempo que permita, puede calentar los cachés de la siguiente manera:

Para cada mesa TableT

  • Ir a cada índice NDX
  • para cada índice NDX
    • ejecute SELECT cada columna en NDX, al menos una columna no indexada en TableT desde TableT

Al hacer esto, garantiza que cada página de datos e índice se lea al menos una vez. Se sentarán en el caché. Este concepto es practicado, en parte y en principio, por Percona . Percona construyó este concepto en mk-slave-prefetch . Lo que hace este programa es

  • leer registros de retransmisión en un esclavo delante del esclavo que procesa el SQL en él
  • tome una instrucción SQL del registro de retransmisión y conviértala en SELECCIONAR utilizando las cláusulas WHERE, GROUP BY y ORDER BY como guía para elegir índices
  • ejecutar la instrucción SELECT que vino del SQL convertido

Esto obliga al esclavo a tener el 99.99% de los datos que necesita para procesar el SQL rápidamente. Esto también hace que el esclavo esté preparado en caso de que usted realice una conmutación por error manual al esclavo y lo promocione a un maestro CUANDO LOS CACHÉ SÓLO SON IGUALES COMO EL MAESTRO DEL QUE FALLÓ.

CONCLUSIÓN

No hay nada mejor que tener cachés listos, dispuestos y capaces de usar en un entorno de INSERTOS, ACTUALIZACIONES y DELETES pesados.

Darle una oportunidad !!!

CONSIDERACIÓN

Con el nacimiento de productos como memcached, algunos se han librado de la necesidad de realizar un ajuste adecuado de MySQL. Por supuesto, muchos sitios se benefician del impulso en la recuperación de datos que se proporciona al controlar el comportamiento de almacenamiento en caché de los datos como los desarrolladores han visto rápidamente con memcached. Muchos otros sitios, simplemente cambiando los motores de almacenamiento o configurando MySQL correctamente, se han dado cuenta de los mismos beneficios de rendimiento. Antes de renunciar a la base de datos y usarla estrictamente como repositorio, aproveche al máximo su base de datos. Siga con la debida diligencia y se sorprenderá gratamente de lo que MySQL hará por usted.

RolandoMySQLDBA
fuente
5

Si esa es una mala solución dependería de muchas cosas. ¿Es necesario que estos datos sean persistentes? De lo contrario, tal vez una solución que simplemente mantenga estos datos en la memoria funcione mejor.

"Muchos usuarios" realmente no está ayudando a nadie. MySQL probablemente estará bien si "mucho" significara unos pocos cientos. (Aunque dependiendo de qué otra cosa tenga que manejar su base de datos. Probablemente varios miles también deberían funcionar).

Después de todo, no importa mucho, si escribe esos registros para conservarlos o eliminarlos después de unos segundos o minutos. Eliminar solo hace dos operaciones de una. Y MySQL puede manejar una gran cantidad de creación y eliminación de registros. Asegúrese de usar un índice simple para encontrar esos registros nuevamente para eliminarlos.

Pero sin números reales y alguna información sobre el hardware que utiliza su servidor de bases de datos, eso no puede responderse con mucha precisión.

Lo mejor sería escribir una pequeña aplicación, que simplemente simule la cantidad de carga que cree que obtendrá sin realizar un procesamiento real, simplemente suelte muchos registros en el servidor, elimínelos, al mismo ritmo ejecute algunas consultas como resto de su programa generaría. Eche un vistazo a su servidor y vea si eso lo afecta de alguna manera.

No estoy seguro, pero hay opciones para configurar MySQL que le permitirían almacenar en caché una tabla en la memoria por completo. Lo hace de todos modos en muchas situaciones y lo más probable es que no tenga que cambiar mucho. Pero si habla de una gran cantidad de usuarios y registros, tal vez pueda modificar algunos parámetros para optimizar el almacenamiento en caché para sus necesidades especiales.

Thorsten Müller
fuente
44
+1 por sugerir una solución que mantiene los datos en la memoria.
3

Aquí hay una idea loca . Implica suposiciones y no siempre prácticas recomendadas (como actualizar una clave). Obtendré muchos puntos negativos por sugerir esto, pero aquí va ...

Suponiendo que tiene un volumen muy alto de filas y un alto volumen de eliminaciones, puede mejorar el rendimiento de eliminación creando 2 particiones en su tabla. Las particiones diferirían en el primer dígito de la clave. Ejemplo:

El valor clave 1123234441 es para filas activas y el valor clave: 9123234441 es para filas inactivas (el primer dígito en este ejemplo se usa de la siguiente manera: 1 = activo, 9 = inactivo).

Ahora, cuando el usuario elimina una fila, no elimina físicamente la fila, actualiza la clave (¡Ay!), Esto movería automáticamente la fila a la partición de filas inactivas.

Por supuesto, debe restringir sus selecciones para leer datos de la partición activa solamente. Ahora lo bueno es que soltar la partición de filas inactivas es extremadamente rápido.

Como dije anteriormente, esto funciona si solo tiene 1 tabla. No he probado esto, por lo que es solo un enfoque teórico, pero he experimentado la velocidad de caída de la partición y es increíblemente rápido.

Para mejorar sus selecciones, use la indexación adecuada y para mejorar las inserciones minimice el tamaño de la fila y el número de índices (esta declaración es muy genérica ...)

Para obtener una referencia, consulte: http://dev.mysql.com/doc/refman/5.1/en/partitions-types.html Espero que esto ayude.

Ninguna posibilidad
fuente
2
No estoy seguro, si esto tiene sentido para este problema específico (supongo que mysql almacenará en caché todo y lo más probable es que esos registros no vean un disco). Pero +1 por señalar una interesante técnica de optimización que no conocía por ahora.