2009-08-31 9 views
10

Tengo una base de datos MySQL con una tabla MyISAM con 4 millones de filas. Actualizo esta tabla una vez a la semana con aproximadamente 2000 nuevas filas. Después de la actualización, entonces me altere la tabla de la siguiente manera:MySQL ALTER TABLE en una mesa muy grande: ¿es seguro ejecutarlo?

ALTER TABLE x ORDER BY PK DESC 

he pedido la mesa por el campo de clave principal en orden descendente. Esto no me ha dado ningún problema en mi máquina de desarrollo (Windows con memoria de 3GB). Tres veces lo he intentado con éxito en el servidor Linux de producción (con 512 MB de RAM y alcanzando la tabla ordenada resultante en aproximadamente 6 minutos cada vez), la última vez que lo probé tuve que detener la consulta después de unos 30 minutos y reconstruir el base de datos de una copia de seguridad.

¿Puede un servidor de 512 MB hacer frente a esa declaración alternativa en una tabla tan grande? He leído que se crea una tabla temporal para realizar el comando ALTER TABLE.

Pregunta: ¿Se puede ejecutar este comando alter con seguridad? ¿Cuál debería ser el tiempo esperado para la alteración de la mesa?

+1

Creo que "Tabla muy grande" es probablemente una exageración. 4M filas no es una tabla muy grande. 1 billón podría ser. – MarkR

Respuesta

0

Probablemente crearía una Vista que está ordenada por el valor de PK, por lo que, para empezar, no es necesario que bloquee esa gran tabla mientras se está ejecutando ALTER.

+0

Gracias por la respuesta ... La cosa es que no me importa bloquear la mesa durante la actualización, ya que estará fuera de línea de todos modos ... –

+0

No creo que una vista ayude aquí. MySQL tiene [dos estrategias] [1] para resoluciones de vista: 'MERGE' y' TEMPTABLE'. Al usar la fusión, no obtendría ningún beneficio ya que su definición simplemente se fusiona con la declaración 'SELECT' presentada. 'TEMPTABLE', como su nombre indica, creará una tabla temporal. Pero la forma en que se ve, la creación de la tabla temporal es la causa del problema original. Así que no ganarías nada excepto hacer el mantenimiento más difícil. [1]: http://dev.mysql.com/doc/refman/5.0/en/view-algorithms.html – exhuma

3

Como acabo de leer, la consulta ALTER TABLE ... ORDER BY ... es útil para mejorar el rendimiento en ciertos escenarios. Me sorprende que el índice PK no ayude con esto. Pero, desde the MySQL docs, parece que InnoDB hace usa el índice. Sin embargo, InnoDB tiende a ser más lento que MyISAM. Dicho esto, con InnoDB no necesitarías volver a ordenar la tabla, pero podrías perder la velocidad de MyISAM. Todavía puede valer la pena intentarlo.

La forma en que explicas los problemas, parece que hay demasiados datos cargados en la memoria (¿tal vez incluso está sucediendo el intercambio?). Podrías verificarlo fácilmente controlando el uso de tu memoria. Es difícil decirlo ya que no conozco bien a MySQL.

Por otro lado, creo que su problema se encuentra en un lugar muy diferente: está utilizando una máquina con solo 512 Megs de RAM como servidor de base de datos con una tabla que contiene más de 4Mio filas ... Y está realizando un operación muy pesada de memoria en toda la mesa en esa máquina. Parece que 512Megs no será suficiente para eso.

Un problema mucho más fundamental que estoy viendo aquí: estás haciendo un desarrollo (y probablemente también pruebas) en un entorno que es muy diferente al entorno de producción. El tipo de problema que está explicando es de esperar. Su máquina de desarrollo tiene seis veces más memoria que su máquina de producción. Creo que puedo decir con seguridad, que el procesador es mucho más rápido también. En ese caso, le sugiero que cree una máquina virtual que imite su sitio de producción. De esta forma, puede probar fácilmente su proyecto sin interrumpir el sitio de producción.

+0

Las mejoras recientes a InnoDB lo han hecho funcionar a la par con MyISAM en la mayoría de los escenarios. –

+0

@Bill: Interesante. Entonces con eso, ¿podrías decir que InnoDB realmente es el camino a seguir? Mismo rendimiento, más funciones. Después de ver tu perfil, creo que puedo creerte. Aún así, ¿tiene alguna prueba para ir con eso? – exhuma

0

Lo que está pidiendo que haga es reconstruir toda la tabla y todos sus índices; esta es una operación costosa, particularmente si los datos no encajan en el RAM. Se completará, pero será mucho más lento si los datos no encajan en RAM, especialmente si tiene muchos índices.

Me pregunto su opinión al elegir ejecutar una máquina con tan poca memoria en producción. De todos modos:

  • ¿Es esto ALTER TABLE realmente necesario; ¿Qué consulta específica estás tratando de acelerar y has intentado sin ella?
  • ¿Ha considerado hacer que su máquina de desarrollo se parezca más a la producción?Quiero decir, usar una caja dev con MÁS memoria nunca es una buena idea, y usar un sistema operativo diferente definitivamente tampoco lo es.

Probablemente también hay algo de ajuste que puede hacer para tratar de ayudar; depende en gran medida de su esquema (índices en particular). Las filas de 4M no son muchas (para una máquina con cantidades normales de ram).

+0

Hola, Mark ... gracias por tu respuesta ... El límite en la memoria se debe a consideraciones presupuestarias ... Pensé que si el sitio detectaba actualizaría las especificaciones del servidor ... Sin embargo, el motivo de hacer ALTER es que los usuarios pueden ejecutar un procedimiento almacenado que consulta esta tabla y quiero devolver los resultados en orden de "último insertado primero". Puedo lograr esto usando un ORDER BY en la consulta en sí, pero desafortunadamente esto parece ser muy costoso y ralentiza las consultas considerablemente ... Por lo tanto, cuando actualizo la tabla, generalmente ordeno por PK desc para omitir este ORDER BY. –

+0

Debe crear un índice apropiado para que la consulta ORDER BY no necesite ordenar. Puede verificar esto usando EXPLAIN (solo si la consulta no está en un SP). ALTER TABLE ... ORDER BY no es una solución, ya que no garantiza que los datos se mantengan ordenados. – MarkR

+0

Hola Mark. Tengo 8 índices en esta tabla. Si tuviera que agregar el campo PK (que deseo ordenar por desc) a la parte más a la derecha de cada uno de estos índices, los índices se seguirán usando para satisfacer la cláusula WHERE y, aunque el campo de ordenamiento no será el más a la izquierda prefijo del índice (como lo voy a agregar a la derecha de cada índice), ¿todavía se puede usar para ORDER BY? Gracias. –

0

Si está utilizando InnoDB, no debería tener que realizar explícitamente el ORDER BY ya sea después de la inserción o en el momento de la consulta. De acuerdo con el manual de MySQL 5.0, InnoDB ya por defecto a ordenar la clave principal para resultados de la consulta:

http://dev.mysql.com/doc/refman/5.0/en/alter-table.html#id4052480

tablas MyISAM devuelven registros con el fin de inserción por defecto, en cambio, que puede funcionar bien si sólo se anexa nunca la tabla, en lugar de utilizar una consulta UPDATE para modificar las filas en el lugar.

1

es la clave principal auto_increment? si es así, entonces hacer ALTER TABLE ... ORDER BY no va a mejorar nada ya que todo se insertará en orden de todos modos.

(a menos que tenga muchas eliminaciones)

+0

Gracias por la respuesta. Sin embargo, el problema es que quiero dar los resultados en orden inverso al orden de las teclas primarias ... –

+1

, entonces debe optimizar los procedimientos almacenados, las consultas y la configuración del servidor, sin intentar cosas de magia negra como ALTER TABLE, que solo funciona debido a una peculiaridad en las tablas myisam. si el rendimiento de sus procedimientos almacenados y consultas sufre al ordenarlos, entonces debe abrir una nueva pregunta y publicar la instrucción CREATE TABLE, la consulta/procedimiento y la salida EXPLAIN. entonces podemos ayudarlo a optimizar la consulta o la configuración de su servidor. – longneck

Cuestiones relacionadas