¿Cómo mejorar MySQL INSERT y ACTUALIZAR el rendimiento?

14

Esta pregunta probablemente también se pueda hacer en StackOverflow, pero primero intentaré aquí ...

El rendimiento de las instrucciones INSERT y UPDATE en nuestra base de datos parece ser degradante y causar un bajo rendimiento en nuestra aplicación web.

Las tablas son InnoDB y la aplicación utiliza transacciones. ¿Hay algunos ajustes fáciles que pueda hacer para acelerar las cosas?

Creo que podríamos estar viendo algunos problemas de bloqueo, ¿cómo puedo averiguarlo?

mmattax
fuente
Mejor en dba.stackexchange.com
Pacerier

Respuestas:

25
  1. Compruebe si su hardware y sistema operativo están configurados y ajustados correctamente:

    • Fuente del problema (CPU / IO / Memoria / Uso de intercambio). ¿Tienes muchas PIO? ¿Están cargadas las CPU? Si tiene muchas IOP leídas, probablemente no tenga suficientes InnoDB buffer_pool. Si la CPU está cargada, probablemente sus consultas realicen escaneos completos de la tabla en lugar de usar índices adecuados.
    • Configuración de disco / RAID / LVM. En algunas configuraciones específicas, el trazado de bandas LVM podría brindarle beneficios al igualar la carga del disco (sin RAID de hardware, múltiples LUNS conectados)
    • IO Scheduler: cuando tiene un buen controlador RAID de hardware, probablemente noop es el mejor. RedHat hizo algunas pruebas y dijeron que para Oracle (y otros DB) CFQ es la mejor opción. Debe ejecutar algunos puntos de referencia (como tpc-c o tpc-e) y elegir qué es lo mejor para su hardware.
    • Buen sistema de archivos: ext3 no funciona bien en cargas de trabajo específicas de bases de datos. Mejor es XFS u OCFS2. Necesitas algunos puntos de referencia nuevamente.
    • Mire, si su sistema usa swap. El uso de intercambio degrada el rendimiento de mysql .
  2. Compruebe, si su instancia de MySQL / InnoDB está ajustada correctamente:

    • tamaño de agrupación de almacenamiento intermedio: páginas de datos de caché en memoria
    • innodb_flush_method = O_DIRECT - evitar el doble buffer IO
    • aumentar el tamaño del archivo de registro de InnoDB: para una carga de trabajo de escritura intensiva, esto podría mejorar el rendimiento. Pero recuerde: un tamaño de archivo de registro más grande significa una recuperación más prolongada. A veces en horas !!!
    • innodb_flush_log_at_trx_commit = 0 o 2: si no le preocupa ACID y puede perder transacciones durante el último segundo o dos.
    • key_buffer_size: muy importante para MyISAM, pero se usa para tablas temporales de disco.
    • Mire su estado INNODB
  3. Analice su carga de trabajo: capture todas sus consultas para registrar lentamente la consulta y ejecute mk-query-digest en ella. Puede capturar todas las consultas usando tcpdump y maatkit
    • ¿Qué consultas toman la mayor parte de su tiempo de servidor?
    • ¿Se crean tablas temporales, especialmente tablas temporales grandes?
    • Aprender, cómo usar explicar
    • ¿Su aplicación utiliza transacciones? Cuando ejecuta consultas con autocommit = 1 (predeterminado en MySQL), cada consulta de inserción / actualización comienza una nueva transacción, que genera algunos gastos generales. Si es posible, es mejor deshabilitar la confirmación automática (en Python MySQL, la confirmación automática del controlador está deshabilitada de forma predeterminada) y ejecutar manualmente la confirmación después de que se realizan todas las modificaciones.
    • ¿Su aplicación realiza series de inserciones en la misma tabla en un bucle? Load data infileEl comando es mucho más rápido para series de inserciones.
    • Recuerde: select count(*) from table;es mucho más lento para innodb que para myisam.
    • ¿Qué tipos de consultas INSERT / UPDATE toman la mayor parte del tiempo del servidor? ¿Cómo se pueden optimizar?
    • Compruebe si su base de datos tiene índices adecuados y agréguelos, si es necesario.

En nuestro entorno tuvimos una situación, ese tipo de consultas de actualización fue lento. ¡El tiempo estimado para terminar el trabajo por lotes fue de 2 días! Después de analizar el registro de slowquery, encontramos que este tipo de consulta de actualización necesita 4 segundos para completarse. Consulta se veía así: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Después de convertir la consulta de actualización a consulta de selección y ejecutar, explicar en esa consulta de selección que encontramos, que este tipo de consulta no usa índice. Después de crear el índice adecuado, redujimos el tiempo de ejecución de la consulta de actualización a milisegundos y el trabajo completo terminó en menos de dos horas.

Algunos enlaces útiles:

sumar
fuente
Ante todo eso revise los índices. OLORES degradantes como "a medida que las tablas se hacen más grandes porque no tenemos índices".
TomTom
5

Con la configuración predeterminada de innoDB, estará limitado a qué tan rápido puede escribir y vaciar transacciones en el disco. Si puede lidiar con perder un poco de ACID, experimente con innodb_flush_log_at_trx_commit. Establezca en 0 para escribir y vaciar el registro al disco aproximadamente cada segundo. Establezca en 1 (predeterminado) para escribir y vaciar en cada confirmación. Establezca en 2 para escribir en el archivo de registro después de cada confirmación, pero enjuague solo una vez por segundo.

Si puede lidiar con la pérdida de 1s de transacciones, esta puede ser una excelente manera de mejorar enormemente el rendimiento de escritura.

Además, preste atención a lo que están haciendo sus discos. RAID 10> RAID 5 para escrituras a costa de un disco adicional.

tomchuk
fuente
1

Los problemas de bloqueo se verán afectados por los estados de conexión en show full processlist;

Lea la my.cnfdocumentación y MySQL. Las opciones de configuración están muy bien documentadas.

En términos generales, desea que se procesen tanto en la memoria como sea posible. Para la optimización de consultas, eso significa evitar tablas temporales. Aplicación adecuada de índices.

El ajuste será específico para su motor de base de datos preferido y la arquitectura de la aplicación. Hay recursos sustanciales preexistentes a una búsqueda en Internet.

Warner
fuente
0

InnoDB es un motor bastante bueno. Sin embargo, depende en gran medida de estar 'sintonizado'. Una cosa es que si sus inserciones no están en el orden de aumentar las claves primarias, innoDB puede tardar un poco más que MyISAM. Esto se puede superar fácilmente configurando un mayor innodb_buffer_pool_size. Mi sugerencia es establecerlo en 60-70% de su RAM total. Estoy ejecutando 4 servidores de este tipo en producción ahora, insertando alrededor de 3,5 millones de filas por minuto. Ya tienen cerca de 3 terabytes. InnoDB tenía que ser, debido a las inserciones altamente concurrentes. Hay otras formas de acelerar las inserciones. Y he comparado algunos.

Ajay Divakaran
fuente
0

Cómo resuelvo los problemas de inserción y actualización de rendimiento en MySQL en la aplicación web simplemente deshabilitando los cambios de confirmación automática y confirmación una vez en Java. Como se sugiere en la documentación de mysql.

Documentos de MySQL

Jatinder
fuente