Tengo una tabla InnoDB que quiero modificar. La tabla tiene ~ 80 millones de filas y abandona algunos índices.
Quiero cambiar el nombre de una de las columnas y agregar algunos índices más.
- ¿Cuál es la forma más rápida de hacerlo (suponiendo que pueda sufrir incluso el tiempo de inactividad, el servidor es un esclavo no utilizado)?
- ¿Es un "simple"
alter table
, la solución más rápida?
En este momento, todo lo que me importa es la velocidad :)
mysql
innodb
alter-table
ddl
Corrió
fuente
fuente
SHOW CREATE TABLE tblname\G
la columna que debe modificarse, el tipo de datos de la columna y el nuevo nombre de la columna.sent_at
y para agregarle algunos índices másRespuestas:
Una forma segura de acelerar una ALTER TABLE es eliminar índices innecesarios
Estos son los pasos iniciales para cargar una nueva versión de la tabla.
Tenga en cuenta lo siguiente:
Descarté source_persona_index porque es la primera columna en otros 4 índices
Descarté target_persona_index porque es la primera columna en otros 2 índices
Descarté target_persona_relation_type_index porque las primeras 2 columnas también están en target_persona_relation_type_message_id_index
OK Eso se encarga de índices innecesarios. ¿Hay algún índice que tenga baja cardinalidad? Aquí está la forma de determinar eso:
Ejecute las siguientes consultas:
Según su pregunta, hay alrededor de 80,000,000 de filas. Como regla general, MySQL Query Optimizer no usará un índice si la cardinalidad de las columnas seleccionadas es mayor que el 5% del recuento de filas de la tabla. En este caso, eso sería 4,000,000.
COUNT(DISTINCT sent_at)
> 4,000,000ALTER TABLE s_relations_new DROP INDEX sent_at_index;
COUNT(DISTINCT message_id)
> 4,000,000ALTER TABLE s_relations_new DROP INDEX message_id_index;
COUNT(DISTINCT target_object_id)
> 4,000,000ALTER TABLE s_relations_new DROP INDEX target_object_index;
Una vez que se ha determinado la utilidad o inutilidad de esos índices, puede volver a cargar los datos.
Eso es todo, ¿verdad? NO !!!
Si su sitio web ha estado activo todo este tiempo, puede haber INSERTs ejecutándose contra s_relations durante la carga de s_relations_new. ¿Cómo puedes recuperar esas filas que faltan?
Busque la identificación máxima en s_relations_new y agregue todo después de esa ID de s_relations. Para garantizar que la tabla se congele y se use solo para esta actualización, debe tener un poco de tiempo de inactividad para obtener las últimas filas que se insertaron en s_relation_new. Aquí está lo que haces:
En el sistema operativo, reinicie mysql para que nadie más pueda iniciar sesión pero root @ localhost (deshabilita TCP / IP):
A continuación, inicie sesión en mysql y cargue esas últimas filas:
Luego, reinicie mysql normalmente
Ahora, si no puede eliminar mysql, tendrá que hacer un cebo y activar s_relations. Simplemente inicie sesión en mysql y haga lo siguiente:
Darle una oportunidad !!!
PRECAUCIÓN: una vez que esté satisfecho con esta operación, puede abandonar la tabla anterior lo antes posible:
fuente
La respuesta correcta depende de la versión del motor MySQL que esté utilizando.
Si utiliza 5.6+, los cambios de nombre y la adición / eliminación de índices se realizan en línea , es decir, sin copiar todos los datos de la tabla.
Solo utilícelo
ALTER TABLE
como de costumbre, será casi instantáneo para los cambios de nombre e índices, y razonablemente rápido para la adición de índices (tan rápido como leer toda la tabla una vez).Si usa 5.1+ y el complemento InnoDB está habilitado, también se agregarán / eliminarán índices en línea. No estoy seguro sobre los cambios de nombre.
Si usa una versión anterior,
ALTER TABLE
sigue siendo la más rápida, pero probablemente será terriblemente lenta porque todos sus datos se volverán a insertar en una tabla temporal debajo del capó.Finalmente, es hora de desacreditar el mito. Desafortunadamente, no tengo suficiente karma aquí para comentar las respuestas, pero creo que es importante corregir la respuesta más votada. Esto esta mal :
En realidad es al revés .
Los índices son útiles para seleccionar pocas filas, por lo que es importante que tengan una alta cardinalidad, lo que significa muchos valores distintos y estadísticamente pocas filas con el mismo valor.
fuente
RENAME TABLE
instantáneo (como se esperaba), peroCHANGE COLUMN
al cambiar el nombre de la clave primaria hice una copia completa ... ¡7 horas! ¿Posiblemente solo porque era la clave principal? No está bien.Tuve el mismo problema con Maria DB 10.1.12, luego, después de leer la documentación, descubrí que hay una opción para realizar la operación "en el lugar" que elimina la copia de la tabla. Con esta opción, la tabla alter es muy rápida. En mi caso fue:
Esto es muy rápido. Sin la opción del algoritmo, nunca terminaría.
https://mariadb.com/kb/en/mariadb/alter-table/
fuente
Para el cambio de nombre de la columna,
debe estar bien y no llevar ningún tiempo de inactividad.
Para los índices, la instrucción CREATE INDEX bloqueará la tabla. Si se trata de un esclavo no utilizado, como mencionaste, no es un problema.
Otra opción sería crear una tabla nueva que tenga los nombres e índices de columna adecuados. Luego podría copiar todos los datos en él, luego ejecutar una serie de
Esto minimizaría el tiempo de inactividad a costa de usar temporalmente el doble de espacio.
fuente
También tengo este problema y usé este SQL:
Espero que pueda ayudar a alguien
Saludos,
Será
fuente