Pregunta

Ejecutamos un servidor MySQL con carga moderada (200-300 QPS) en hardware bastante potente (HP DL360 con 8 núcleos Xeon, 8Gb RAM y RAID10). Todas las tablas son innodb y el conjunto de datos activo se ajusta dentro del innodb_buffer_pool_size asignado.

Nuestra base de datos está normalizada y para reducir el número de uniones usamos vistas materializadas para aplanar el conjunto de datos. A medida que los datos se agregan en lotes varias veces al día, los MV: s se regeneran usando CREATE TABLE AS SELECT en lugar de actualizarse dinámicamente usando activadores complejos.

El problema es que a veces, mientras se ejecutan estas consultas CREATE (cada una de las cuales toma de 5 a 50 segundos), otras consultas no relacionadas con el servidor parecen estar en cola detrás de CREATE consulta, que conduce a una base de datos que no responde.

Para (re) generar los MV: s usamos algo como esto:

BEGIN TRANSACTION;
DROP TABLE IF EXISTS TableName_TMP;
CREATE TABLE TableName_TMP ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci AS 
    SELECT about100columns, and10Expressions 
    FROM Table1 
    JOIN Table2 ON Table1.fk = Table2.pk 
    /* join up to 13 other tables */
    WHERE ((removed IS NULL OR removed = 0)) 
    ORDER BY created DESC, id ASC;
ALTER TABLE TableName_TMP ADD PRIMARY KEY(id), INDEX(created);
DROP TABLE IF EXISTS TableName;
ALTER TABLE TableName_TMP RENAME TO TableName;
COMMIT;

La EXPLICACIÓN de SELECT produce algo como:

+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+
| id | select_type | table            | type        | possible_keys | key        | key_len | ref                          | rows  | Extra                       |
+----+-------------+------------------+-------------+---------------+------------+---------+    ------------------------------+-------+-----------------------------+
|  1 | SIMPLE      | Table1           | ref_or_null | removed       | removed    | 5       | const                        | 76093 | Using where; Using filesort | 
|  1 | SIMPLE      | Table2           | eq_ref      | PRIMARY       | PRIMARY    | 4       | Table1.fk1                   |     1 |                             | 
|  1 | SIMPLE      | Table3           | eq_ref      | PRIMARY       | PRIMARY    | 4       | Table1.fk2                   |     1 |                             | 
/* More of the same */
|  1 | SIMPLE      | TableN           | eq_ref      | PRIMARY       | PRIMARY    | 4        | TableM.fk                    |     1 | Using index                 | 
|  1 | SIMPLE      | TableX           | eq_ref      | PRIMARY       | PRIMARY    | 4       | TableY.fk                    |     1 |                             | 
/* More of the same */    
+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+

¿Alguna idea de por qué CREATE TABLE AS sobrecarga completamente nuestro servidor y cómo puedo evitarlo?

Saludos,

¿Fue útil?

Solución

Resolvimos esto cambiando a SELECT INTO y LOAD DATA INFILE como http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/ . Muchas gracias a Randolph Potter por enviarnos en la dirección correcta.

Otros consejos

¿Podría ser esta la causa?

Nota: DROP TABLE confirma automáticamente la transacción activa actual, a menos que use la palabra clave TEMPORAL.

( http://dev.mysql.com/ doc / refman / 5.1 / es / drop-table.html )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top