Agregar índice a tablas mysql grandes

13

Tengo una mesa

El | base_schedule_line_items | CREATE TABLE base_schedule_line_items(
idint (10) unsigned NOT NULL AUTO_INCREMENT,
installmentint (10) unsigned NOT NULL,
on_datedate NOT NULL,
actual_datedate DEFAULT NULL,
payment_typeint (11) NOT NULL,
scheduled_principal_outstandingdecimal (65,0) NOT NULL,
scheduled_principal_duedecimal (65,0) NOT NULL,
scheduled_interest_outstandingdecimal (65,0) NOT NULL,
scheduled_interest_duedecimal (65,0) NOT NULL,
currencyint (11) NOT NULL,
updated_atdatetime NOT NULL DEFAULT '2013-01-06 14:29:16',
created_atdatetime NOT NULL DEFAULT ' 2013-01-06 14:29:16 ',
loan_base_schedule_idint (10) unsigned NOT NULL,
lending_idint (10) unsigned NOT NULL,
rescheduletinyint (1) DEFAULT' 0 ',
PRIMARY KEY ( id),
KEY index_base_schedule_line_items_loan_base_schedule ( loan_base_schedule_id), KEY index_bslt_spd( scheduled_principal_due),
CLAVE index_bslt_lending(lending_id),
KEY index_bslt_actualdate( actual_date),
CLAVE index_bslt_spsila ( loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date),
KEY index_bslt_ondate( on_date),
CLAVE index_bslt_oa( on_date, actual_date),
CLAVE index_bslt_ol( on_date, loan_base_schedule_id),
CLAVE index_bslt_oli( on_date, lending_id)
) ENGINE = InnoDB AUTO_INCREMENT = 30410126 DEFAULT charset = UTF-8 |

Ahora, esta tabla tiene 30 millones de registros, necesito agregar dos índices más y es como si llevara años agregarla.

alterar tabla base_schedule_line_items agregar índice index_bslt_sla (calendar_principal_due, actual_date, lending_id);
alter table base_schedule_line_items add index index_bslt_ssla (Scheduled_principal_due, Scheduled_interest_due, Lending_id, actual_date);

Usé la consulta mencionada a continuación para averiguar el tamaño de la tabla

SELECCIONE table_name AS "Tables", round (((data_length + index_length) / 1024/1024), 2) "Size in MB" FROM information_schema.TABLES WHERE table_schema = "my_database_name";

El resultado salió como

base_schedule_line_items | 20111.00

Utilicé esto solo para calcular la longitud de los datos y omití la longitud del índice

SELECCIONE table_name AS "Tables", round (((data_length) / 1024/1024), 2) "Size in MB" FROM information_schema.TABLES WHERE table_schema = "my_database_name";

y el resultado fue

base_schedule_line_items | 9497.00

Los índices

Index_bslt_actualdate KEY (actual_date),
index_bslt_spsila KEY (loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date),
index_bslt_ondate KEY (on_date),
index_bslt_oa KEY (on_date, actual_date),
index_bslt_ol KEY (on_date, loan_base_schedule_id),
index_bslt_oli KEY (on_date, lending_id)

fueron agregados por mí, pero no estoy seguro o para qué propósito se agregaron otros índices. Esta es una aplicación bastante grande. Ahora necesito agregar esos dos índices mencionados anteriormente, ya que me ayudan a extraer un informe usando una instrucción select y me resulta muy difícil agregarlos. Cualquier ayuda sería muy apreciada

usuario2294477
fuente

Respuestas:

16

La actividad de alterar tablas grandes se realiza en fases:

  1. Cree una nueva tabla con los campos e índices obligatorios, por ejemplo, en la prueba DB (solo estructura)
  2. Volcar los datos de la tabla existente y cargarlos en la tabla recién creada en la base de datos de prueba
  3. Ahora anuncia tu tiempo de inactividad :)
  4. Cambie las tablas cambiando el nombre: RENAME table ur_db.table_name to test.temp, test.table_name to ur_db.table_name, test.temp to test.table_name;esta es una operación atómica que toma una fracción de segundo.
  5. Cargue los registros adicionales en la tabla recién creada (los registros que vinieron después de volcar y luego cargar). Este paso se puede hacer antes del Paso: 3 también una vez para reducir el tiempo de inactividad.
  6. Y tu sistema está de vuelta

Pocas notas:

  1. No necesita acceder al esquema de información directamente de esta manera, intente usar SHOW TABLE STATUS from db like 'table_name'
  2. La velocidad de la tabla alter está más o menos vinculada con la velocidad de E / S. La última vez que ejecutamos una tabla alternativa directa (sin los pasos anteriores), teníamos un tamaño de tabla de más de 40 GB que tardó alrededor de 4 horas. Si sus datos de 20 GB tardan años, está trabajando en una máquina obsoleta.
  3. También la caída de los índices no deseados, index_bslt_ondate, index_base_schedule_line_items_loan_base_schedulecomo algunos otros índices tiene la columna más a la izquierda como la columna indexada

Avíseme si necesita alguna aclaración sobre alguno de estos pasos.

Editar: un script de Python simple para automatizar el proceso https://github.com/georgecj11/hotswap_mysql_table.git

georgecj11
fuente
10

Puede usar una herramienta como pt-online-schema-change para agregar el índice sin bloquear su aplicación. La lógica básica es la siguiente:

  • crear una copia vacía de la tabla con el nuevo índice
  • agregue desencadenantes a la tabla existente para que cualquier cambio que golpee la tabla se aplique a la copia de la tabla *
  • comience a copiar las filas de la tabla anterior a la nueva
  • una vez completada la copia, cambie las tablas
  • dejar caer la vieja mesa

* La herramienta no funciona si hay activadores existentes en la tabla

El comportamiento de intercambio y caída se puede ajustar en función de las opciones pasadas a la herramienta.

Además, existen problemas con las claves externas, así que asegúrese de leer la documentación de la herramienta para comprender completamente lo que está haciendo.

Y, por supuesto, es aconsejable asegurarse de tener una copia de seguridad de la tabla para poder restaurarla si es necesario.

Derek Downey
fuente