Domanda

Eseguiamo un server MySQL con carico moderato (200-300 QPS) su hardware abbastanza potente (HP DL360 con 8 core Xeon, 8Gb RAM e RAID10). Tutte le tabelle sono innodb e il set di dati attivo rientra nel innodb_buffer_pool_size .

Il nostro database è normalizzato e per ridurre il numero di join utilizziamo viste materializzate per appiattire il set di dati. Man mano che i dati vengono aggiunti in batch alcune volte al giorno, gli MV: vengono rigenerati utilizzando CREATE TABLE AS SELECT anziché essere aggiornati dinamicamente utilizzando trigger complessi.

Il problema è che a volte mentre vengono eseguite queste query CREATE (ognuna delle quali impiega dai 5 ai 50 secondi) altre query non correlate al server sembrano essere messe in coda dietro CREATE , che porta a un database che non risponde.

Per (ri) generare il MV: s usiamo qualcosa del genere:

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;

EXPLAIN di SELECT produce qualcosa del tipo:

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

Qualche idea sul perché CREATE TABLE AS sovraccarichi completamente il nostro server e come posso impedirlo?

Saluti,

È stato utile?

Soluzione

Abbiamo risolto il problema passando a SELECT INTO e LOAD DATA INFILE come da http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/ . Mille grazie a Randolph Potter per averci inviato nella giusta direzione.

Altri suggerimenti

Potrebbe essere questa la causa?

Nota: DROP TABLE esegue automaticamente il commit della transazione attiva corrente, a meno che non si usi la parola chiave TEMPORARY.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top