2009-10-26 19 views
5

Después de un crecimiento esperado en nuestro servicio, de repente algunas actualizaciones llevan mucho tiempo, estas solían ser bastante rápidas hasta que la tabla alcanzaba unos 2MM de registros, ahora toman alrededor de 40- 60 segundos cada uno.Toma de actualización MySQL (demasiado) mucho tiempo

update table1 set field1=field1+1 where id=2229230; 
Query OK, 0 rows affected (42.31 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 

Éstos son los tipos de campos:

`id` bigint(20) NOT NULL auto_increment, 
`field1` int(11) default '0', 

resultado de la elaboración de perfiles, para cambios de contexto que es el único que parece tener un número elevado de los resultados:

mysql> show profile context switches 
    -> ; 
+----------------------+-----------+-------------------+---------------------+ 
| Status    | Duration | Context_voluntary | Context_involuntary | 
+----------------------+-----------+-------------------+---------------------+ 
| (initialization)  | 0.000007 |     0 |     0 | 
| checking permissions | 0.000009 |     0 |     0 | 
| Opening tables  | 0.000045 |     0 |     0 | 
| System lock   | 0.000009 |     0 |     0 | 
| Table lock   | 0.000008 |     0 |     0 | 
| init     | 0.000056 |     0 |     0 | 
| Updating    | 46.063662 |    75487 |    14658 | 
| end     | 2.803943 |    5851 |     857 | 
| query end   | 0.000054 |     0 |     0 | 
| freeing items  | 0.000011 |     0 |     0 | 
| closing tables  | 0.000008 |     0 |     0 | 
| logging slow query | 0.000265 |     2 |     1 | 
+----------------------+-----------+-------------------+---------------------+ 
12 rows in set (0.00 sec) 

La tabla contiene aproximadamente 2,5 millones de registros, el ID es la clave principal y tiene un índice único en otro campo (no incluido en la actualización).

It's a innodb table.

¿Alguna indicación sobre cuál podría ser la causa?

¿Alguna variable en particular que pueda ayudar a rastrear el problema?

¿Hay alguna "explicación" para las actualizaciones?

EDIT: También me acabo de dar cuenta que la tabla también tiene una:

`modDate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 

Explicar:

+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra | 
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
| 1 | SIMPLE  | table1  | const | PRIMARY  | PRIMARY | 8  | const | 1 |  | 
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
1 row in set (0.02 sec) 
+0

¿Qué es el tipo de campos 'field1' y' id'? –

+1

Puede tratar de perfilar esta cola. Consulte http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html –

+0

Parece impar: ¿1 fila coincide, pero cero filas afectadas? –

Respuesta

8

No hay manera de que consulta debe tomar mucho tiempo, si la identificación es en realidad el principal clave (a menos que tenga muchos lotes de identificadores igual a 2229230?). Por favor, ejecute los dos sqls siguientes y publicar los resultados:

show create table table1; 
explain select * from table1 where id = 2229230; 

Actualización: sólo para estar completa, también hacen un

select count(*) from table1 where id = 2229230; 
+0

+1 Definitivamente ayudará a ver si hay una definición incorrecta de la tabla si los throws en esta información – Zak

4

Puedo recomendar así:

OPTIMIZE TABLE table1; 

A veces su las tablas solo necesitan un poco de amor, si han crecido rápidamente y no las has optimizado en un momento los índices pueden estar un poco locos. De hecho, si usted tiene el tiempo (y lo hace), nunca está de tirar

REPAIR TABLE table1; 
+0

hay una manera de saber de antemano si la optimización o reparación lo hará hacer algo ? o ejecutarlos es la única opción? – webclimber

+0

@webclimber - Correr localmente le dirá. – Phil

4

Ok después de unas horas de localizar a éste, parece que la causa fue un "índice duplicado" , la mesa que estaba haciendo para responder a Keith crear, tenía esta extraña combinación:

  • una clave única en CampoX
  • una tecla en CampoX

el segundo es obviamente redundante e inútil, pero después de dejar caer ped la clave todas las actualizaciones volvieron a < 1 seg.

+1 a Keith e Ivan, ya que sus comentarios me ayudaron finalmente a rastrear el problema.

1

Lo que ayudó para mí fue cambiar el motor de 'innodb' a 'myisam'. Mi consulta de actualización en un conjunto de datos de tamaño similar pasó de 100 ms a 0.1 ms.

Tenga en cuenta que cambiar el tipo de motor para una aplicación existente puede tener consecuencias ya que InnoDB tiene una mejor integridad de datos y algunas funciones de las que depende su aplicación.

Para mí, valía la pena perder InnoDB por un aumento de velocidad de 1000 veces en grandes conjuntos de datos.

+2

Puede ser peligroso cambiar una aplicación de InnoDB a MyISAM. MyISAM casi no ofrece garantías sobre la integridad de los datos. –

+1

Buen punto, añadiré que a mi respuesta, en un caso donde la aplicación es hecha por la persona que también establece el tipo de motor, es bueno saber que en algunos casos es posible sacrificar la integridad de datos para la velocidad. – Kapytanhook

0

Me encontraría con este mismo problema, que resultó ser debido a un disparador sobre la mesa. Cada vez que se realizaba una actualización en mi tabla, el activador actualizaba otra tabla que era en realidad la causa de la demora. Agregar un índice en esa tabla solucionó el problema. Por lo tanto, intente comprobar si hay factores desencadenantes en la mesa.

0

Otra cosa a tener en cuenta al depurar declaraciones de actualización que toman demasiado tiempo en comparación con la versión de extracto de selección: ¿las sentencias de actualización se ejecutan dentro de una transacción?

En mi caso, una transacción convirtió la (s) declaración (es) de actualización de un tiempo de ejecución tremendamente rápido a uno extremadamente lento. Cuantas más filas afecten, más pesada será la pérdida de rendimiento. Mis declaraciones funcionan con variables definidas por el usuario, pero no sé si esa parte del 'problema'.

Cuestiones relacionadas