2012-03-30 11 views
8

Tengo una tabla mysql con más de 30 millones de registros que originalmente se almacenaban con myisam. He aquí una descripción de la tabla:Diferencia de rendimiento entre Innodb y Myisam en Mysql

describe_table

Me ejecute la siguiente consulta en esta tabla que por lo general toma alrededor de 30 segundos para completar. Cambiaría @eid cada vez para evitar el almacenamiento en caché de la base de datos o el disco.

select count(fact_data.id) 
    from fact_data 
    where [email protected] 
     and fact_data.metric_id=1 

luego convertidos a esta tabla InnoDB sin hacer otros cambios y después, la misma consulta devuelve ahora en menos de un segundo cada vez que ejecuta la consulta. Incluso cuando configuro aleatoriamente @eid para evitar el almacenamiento en caché, la consulta regresa en menos de un segundo.

He estado investigando las diferencias entre los dos tipos de almacenamiento para tratar de explicar la mejora dramática en el rendimiento pero no he podido encontrar nada. De hecho, mucho de lo que leo indica que Myisam debería ser más rápido.

Las consultas que estoy ejecutando están en contra de una base de datos local sin que otros procesos lleguen a la base de datos en el momento de las pruebas.

Respuesta

15

Esa es una diferencia de rendimiento sorprendentemente grande, pero puedo pensar en algunas cosas que pueden estar contribuyendo.

MyISAM ha sido históricamente visto como más rápido que InnoDB, pero para versiones recientes de InnoDB, eso es cierto para un conjunto mucho más pequeño de casos de uso. MyISAM suele ser más rápido para escaneos de tablas de solo lectura. En la mayoría de los casos de uso, normalmente encuentro que InnoDB es más rápido. A menudo muchas veces más rápido. Los bloqueos de mesa son un toque de difuntos para MyISAM en la mayor parte de mi uso de MySQL.

MyISAM almacena en caché los índices en su almacenamiento intermedio de claves. Tal vez haya configurado el búfer clave demasiado pequeño para que pueda almacenar en caché el índice para su tabla algo grande.

MyISAM depende del sistema operativo para almacenar en caché los datos de la tabla de los archivos .MYD en la memoria caché de disco del sistema operativo. Si el sistema operativo se está quedando sin memoria, comenzará a descargar su caché de disco. Eso podría obligarlo a seguir leyendo desde el disco.

InnoDB almacena en caché los índices y los datos en su propio búfer de memoria. Puede decirle al sistema operativo que no use también su caché de disco si establece innodb_flush_method en O_DIRECT, aunque esto no es compatible con OS X.

InnoDB suele almacenar datos e índices en páginas de 16kb. Dependiendo de cómo esté cambiando el valor de @eid entre consultas, es posible que ya haya almacenado en caché los datos de una consulta debido a las lecturas de disco de una consulta previa.

Asegúrese de haber creado los índices de forma idéntica. Use Explain para verificar si MySQL está usando el índice. Dado que incluyó el resultado de describe en lugar de mostrar tabla de creación o mostrar índices desde, no puedo decir si entity_id es parte de un índice compuesto. Si no era la primera parte de un índice compuesto, no se usaría.

Si está utilizando una versión relativamente moderna de MySQL, ejecute el siguiente comando antes de ejecutar la consulta:

conjunto de perfiles = 1;

Eso activará el perfilado de consultas para su sesión. Después de ejecutar la consulta, ejecute

show profiles;

Esto le mostrará la lista de consultas para las que hay perfiles disponibles. Creo que mantiene los últimos 20 por defecto. Suponiendo que su consulta fue la primera, ejecute:

muestre el perfil para la consulta 1;

A continuación, verá la duración de cada etapa al ejecutar su consulta. Esto es extremadamente útil para determinar qué (por ejemplo, bloqueos de tabla, clasificación, creación de tablas temporales, etc.) está causando que una consulta sea lenta.

6

Mi primera sospecha sería que la tabla y/o los índices originales de MyISAM se fragmentaron con el tiempo y el rendimiento se deterioró lentamente. La tabla InnoDB no tendría el mismo problema ya que la creó con todos los datos que ya estaban en ella (por lo que se almacenaría secuencialmente en el disco).

Puede probar esta teoría reconstruyendo la tabla MyISAM. La forma más sencilla de hacerlo sería utilizar un "nulo" ALTER TABLE:

ALTER TABLE mytable ENGINE = MyISAM; 

A continuación, comprobar el rendimiento para ver si es mejor.

Otra posibilidad sería si la base de datos simplemente se sintoniza para el rendimiento de InnoDB en lugar de MyISAM. Por ejemplo, InnoDB usa el innodb_buffer_pool_size parameter para saber la cantidad de memoria que se debe asignar para almacenar datos almacenados en caché e índices en la memoria. Pero MyISAM usa el parámetro key_buffer. Si su base de datos tiene un grupo de búferes innodb grande y un búfer clave pequeño, entonces el rendimiento de InnoDB será mejor que el rendimiento de MyISAM, especialmente para tablas grandes.

+0

Una prueba razonablemente simple de crear una nueva tabla MyISAM y sincronizar la consulta con esa tabla podría confirmar esta suposición. –

1

Cuáles son sus definiciones de índice, hay formas en que puede crear índices para MyISAM en los que sus campos de índice no se utilizarán cuando lo crea.

Cuestiones relacionadas