Cómo optimizar las tablas de InnoDB en MySQL

8

He estado investigando cómo optimizar solo tablas fragmentadas en MySQL y revisé esta publicación sobre la optimización de tablas . Básicamente realiza una consulta en la base de datos information_schema para cualquier tabla con data_free > 0y construye una declaración SQL OPTIMIZEsolo para esas tablas. Ejecuté esta consulta e identificó 148 tablas para la optimización. Todas las tablas identificadas son tablas InnoDB. Después de ejecutar el script SQL de optimización resultante, volví a ejecutar el script original para identificar tablas fragmentadas y devolvió exactamente las mismas tablas durante el primer paso.

He visto publicaciones contradictorias con respecto a las tablas de InnoDB y el OPTIMIZEcomando. Algunos dicen que OPTIMIZEno funcionará con las tablas de InnoDB y que necesita ejecutar ALTER TABLE table_name ENGINE=INNODB. Otros dicen que en OPTIMIZErealidad llama al ALTER TABLEcomando cuando se ejecuta contra tablas InnoDB. Con eso en mente, ejecuté el ALTER TABLEcomando contra una de las tablas de InnoDB identificadas como fragmentadas ( data_free > 0) y descubrí que data_freeno cambió después. Todavía es mayor que 0. También reinicié MySQL y lo comprobé solo para encontrar los mismos resultados.

Ahora, tenemos varios servidores que ejecutan MySQL 5.5.29 en nuestra organización y ejecuté una consulta en todos ellos para identificar las tablas de InnoDB DATA_FREE=0 or NULLy no se devolvió ninguna. Todos son mayores que cero.

También ejecuté el OPTIMIZEcomando contra algunas MyISAMtablas donde DATA_FREEera mayor que cero y luego verifiqué que era cero.

¿Alguien puede arrojar algo de luz sobre esto por mí? ¿Cuál es el método adecuado para eliminar la fragmentación de las tablas de InnoDB? ¿Cuál es el método adecuado para determinar tablas fragmentadas de InnoDB?

Gracias

usuario3151788
fuente

Respuestas:

9

Asumiré que estás usando innodb_file_per_tablepara esta respuesta.

Hay más de un significado para "fragmentación de InnoDB":

  1. .ibd el archivo está fragmentado y es muy grande, mientras que el conjunto de datos es pequeño
  2. Las páginas de índice están fragmentadas porque hay demasiadas páginas para contener pocos datos, en cuyo caso podrían fusionarse.

Considere esta publicación que escribí hace un tiempo: muestra cómo después de purgar muchas filas de una tabla grande, el archivo de datos está fragmentado (es decir, es muy grande en el sistema de archivos; es un problema conocido que estos archivos nunca reducen de tamaño). Y, sin embargo, los índices no estaban fragmentados al final de la eliminación: esto se debe a que InnoDB combina correctamente las páginas a medida que se vuelven vacías (er).

El OPTIMIZEcomando de hecho no se aplica en InnoDB. Lo que hace es reconstruir la tabla (exactamente como una ALTER). Mira esto:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

En cuanto a DATA_FREE: sugiero que simplemente ignore esta variable. Para ser honesto, he estado trabajando con tablas InnoDB durante 10años, y nunca he encontrado que este valor sea muy consistente con nada.

Y ahora es el momento de la verdadera discusión: ¿qué estás tratando de lograr exactamente? A menos que su base de datos esté completamente obsoleta, siempre habrá algo de fragmentación. Es natural en el proceso de agregar, eliminar y actualizar filas en su tabla.

La fragmentación no es tan malvada: los nuevos datos pueden recuperar el espacio libre. Si tus tablas no son muy grandes, entonces olvídate de todo. Para tablas muy grandes, puede ganar algo de espacio en disco optimizando la tabla. Pero pregúntese: ¿qué tan pronto alcanzaría la tabla la misma fragmentación? ¿Una hora? ¿Un día? ¿Una semana? En mi humilde opinión, en todos estos casos no tiene sentido optimizar la tabla.

Sin embargo, si una tabla grande se purga masivamente de datos, que no se espera que regrese, estoy a favor de optimizarla. Supongamos que se da cuenta de que tiene algunos datos redundantes que consisten en aproximadamente el 30% del tamaño de su tabla. Claro, sería genial recuperar ese espacio en disco.

En pocas palabras: solo considere estos problemas con tablas muy grandes; solo si tiene problemas con el espacio en disco.

Shlomi Noach
fuente
Estoy de acuerdo en que data_free no es útil. Solo cuenta el espacio en "extensiones libres" para el espacio de tabla, que es una métrica terrible para calcular la fragmentación. Creo que si no lo está utilizando innodb_file_per_table, también mostrará el mismo valor para cada tabla en el espacio de tabla compartido.
jeremycole