estoy usando y trabajando en el software que utiliza MySQL como motor de backend (se puede usar a otros como PostgreSQL u Oracle o SQLite, pero esta es la principal aplicación que estamos utilizando). El software fue diseñado de tal manera que los datos binarios queremos acceder se mantiene como BLOB en columnas individuales (cada tabla tiene una BLOB columna, otras columnas tienen números enteros/flotadores para caracterizar la BLOB y una cuerda columna con el hash MD5 BLOB). Las tablas tienen típicamente 2, 3 o 4 índices, uno de los cuales es siempre la columna MD5, que se hace UNIQUE
. Algunas tablas ya tienen millones de entradas y han ingresado en el tamaño de varios gigabytes. Mantenemos bases de datos MySQL separadas por año en el mismo servidor (hasta ahora). El hardware es bastante razonable (creo) para aplicaciones generales (un servidor Dell PowerEdge 2U-form).lenta MySQL inserta
MySQL SELECT
consultas son relativamente rápido. Hay poca queja allí, ya que estos son (la mayoría de las veces) en modo por lotes. Sin embargo, las consultas INSERT
tardan mucho tiempo, lo que aumenta con el tamaño de la tabla (número de filas). Es cierto que esto se debe a que la columna MD5 es del tipo UNIQUE
y, por lo tanto, cada INSERT
tiene que determinar si cada nueva fila tiene una cadena MD5 correspondiente, ya insertada. Y no es demasiado extraño (creo) si el rendimiento empeora si hay otros índices (no únicos). Pero todavía no puedo dejar de pensar que esta opción de arquitectura de software (sospecho que mantener BLOBs en la fila de la tabla en lugar de disco tiene un impacto negativo significativo) no es la mejor opción. Las inserciones no son críticas, pero es una sensación molesta tener.
¿Alguien tiene experiencia en situaciones similares? ¿Con MySQL, o incluso con otros RDBM (preferiblemente basados en Linux)? ¿Alguna idea que le gustaría proporcionar, tal vez algunas cifras de rendimiento?
Por cierto, el idioma de trabajo es C++ (que envuelve C llama a la API de MySQL).
La opción BEGIN TRANSACTION parece ser la solución más directa en este momento. Sin embargo, tengo algunas preguntas, ya que no estoy familiarizado con ella (mantendré RTFM mientras tanto). 1) Dado que la API de MySQL está en C, podría ocurrir que nos equivoquemos e intentemos insertar VALORES que apuntan a nulo. Esto seguramente causará que la aplicación del cliente muera con SEGFAULT. ¿La transacción será "sucia" en este caso? ¿Alguna necesidad de limpiar? ¿Cómo? 2) Estamos usando MyISAM. Cambiar a InnoDB ahora puede ser doloroso y/o peligroso. ¿Conoces el rendimiento de TRANSACTION en MyISAM? Gracias de antemano por su comentario. – jbatista
MhISAM no es transaccional, lo que significa que puede ignorar todo lo que escribí sobre transacciones, sin embargo, la instrucción de inserción con varios cientos o miles de insertos en una consulta también acelerará las cosas en MyISAM. – dimus
OK. ¿Sabes si la sintaxis INSERT INTO impone un límite a la longitud de la cadena de consulta? I.o.w., ¿MySQL acepta una cadena de consulta INSERT INTO con una longitud de (por ejemplo) cientos de millones de caracteres? A mí me huele a problema. – jbatista