Question

Nous utilisons un serveur MySQL avec une charge modérée (200-300 QPS) sur un matériel assez puissant (HP DL360 avec 8 cœurs Xeon, 8 Go de RAM et RAID10). Toutes les tables sont innodb et l’ensemble de données actif s’inscrit dans le alloué innodb_buffer_pool_size .

Notre base de données est normalisée et afin de réduire le nombre de jointures, nous utilisons des vues matérialisées pour aplatir l'ensemble de données. Lorsque les données sont ajoutées par lots plusieurs fois par jour, les MV: sont régénérés à l'aide de CREATE TABLE AS SELECT au lieu d'être mis à jour de manière dynamique à l'aide de déclencheurs complexes.

Le problème est que parfois, alors que ces requêtes CREATE sont exécutées (chacune d’elles prend entre 5 et 50 secondes), d’autres requêtes non liées au serveur semblent se mettre en file d'attente derrière le CREATE requête menant à une base de données ne répondant pas.

Pour (re) générer le MV: nous utilisons quelque chose comme ceci:

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;

L’EXPLAIN du SELECT produit quelque chose comme:

+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+
| 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 */    
+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+

Des idées pour lesquelles le CREATE TABLE AS surcharge complètement notre serveur et comment puis-je l’empêcher?

Cordialement,

Était-ce utile?

La solution

Nous avons résolu ce problème en basculant vers SELECT INTO et LOAD DATA INFILE comme suit: http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/ . Un grand merci à Randolph Potter pour nous avoir envoyé dans la bonne direction.

Autres conseils

Cela pourrait-il être la cause?

Remarque: DROP TABLE valide automatiquement la transaction active en cours, sauf si vous utilisez le mot clé TEMPORARY.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top