2011-01-29 2 views
12

Ho la seguente tabella di InnoDB:Mysql Inserire lento

+-----------+-----------+------+-----+-------------------+----------------+ 
| Field  | Type  | Null | Key | Default   | Extra   | 
+-----------+-----------+------+-----+-------------------+----------------+ 
| id  | int(11) | NO | PRI | NULL    | auto_increment | 
| doc_id | char(32) | NO |  | NULL    |    | 
| staff  | char(18) | NO |  | NULL    |    | 
| timestamp | timestamp | NO | MUL | CURRENT_TIMESTAMP |    | 
+-----------+-----------+------+-----+-------------------+----------------+ 

Con questi tasti:

+--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table  | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| staff_online |   0 | PRIMARY   |   1 | id   | A   |  277350 |  NULL | NULL |  | BTREE  |   | 
| staff_online |   1 | timestamp  |   1 | timestamp | A   |  277350 |  NULL | NULL |  | BTREE  |   | 
| staff_online |   1 | staff_timestamp |   1 | timestamp | A   |  277350 |  NULL | NULL |  | BTREE  |   | 
| staff_online |   1 | staff_timestamp |   2 | staff  | A   |  277350 |  NULL | NULL |  | BTREE  |   | 
+--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

Ho appena notato che in mysql-slow.log a volte ho una query di inserimento su questo tavolo che prende più di 1 secondo

INSERT INTO `staff_online` (`doc_id`, `staff`, `timestamp`) VALUES ('150b60a0ab8c5888bdbbb80bd8b7f8a2', 'asia', '2011-01-29 16:52:54') 

sono davvero perplesso perché ci vuole tanto tempo. Come posso accelerarlo?

BTW: Ogni giorno ci sono ~ 80 INSERTI lenti e 40 AGGIORNAMENTI lenti come questo.

+1

quante righe sono in tabella, e sono certo tutti gli inserti sono lenti? –

+1

Ci sono 277259 righe e solo alcuni inserimenti sono lenti (rari). – kalkin

+7

Sembra che tu abbia due indici, uno per 'timestamp' un altro per' timestamp, staff'. Quest'ultimo è sufficiente per cercare per 'timestamp', è possibile eliminare il precedente. – 9000

risposta

10

A volte non è la query stessa a causare un rallentamento: un'altra query che opera sulla tabella può facilmente rallentare gli inserimenti a causa dell'isolamento e del blocco della transazione. Le tue query lente potrebbero semplicemente aver atteso il completamento di un'altra transazione. Questo è abbastanza comune su una tabella occupata o se il server sta eseguendo transazioni lunghe/complesse.

Un altro fattore significativo sarà la performance complessiva del database: come il file my.cnf è sintonizzato, come il server stesso è sintonizzato, che altro il server ha in esecuzione su di esso, e, naturalmente, ciò che l'hardware del server è in esecuzione.

Lo strumento linux mytop e la query SHOW ENGINE INNODB STATUS\G possono essere utili per vedere possibili punti problematici. Gli strumenti generali delle prestazioni di linux possono anche mostrare quanto sono occupati i tuoi dischi, ecc.

Data la natura di questa tabella, hai considerato un modo alternativo per tenere traccia di chi è online? In MySQL, ho usato una tabella MEMORY per tali scopi in passato. Un archivio dati NoSQL potrebbe anche essere utile per questo tipo di informazioni. Redis potrebbe memorizzarlo come un insieme ordinato con molto successo (punteggio == timestamp).

Ulteriori approfondimenti:

+1

Ho aggiunto quanto segue al mio mysql config che dovrebbe ottenere un po 'più di prestazioni. Vedremo. innodb_flush_log_at_trx_commit = 0 innodb_support_xa = 0 innodb_buffer_pool_size = 536.870.912 – kalkin

+0

Btw non posso utilizzare il motore di memoria, perché ho bisogno di avere i dati online in qualche modo persistente, per una successiva analisi. – kalkin

+0

@Kalkin: Sembra una scusa per me - "i requisiti aziendali lo richiedono". A volte esigenze aziendali eccessivamente ampie devono essere rivalutate di fronte a ostacoli tecnici. Consiglierei di ripensare i tuoi requisiti in base a ciò che effettivamente hai bisogno di sapere. Ma nel complesso, il mio post riguarda: non basta guardare questa query, guarda tutto ciò che sta facendo il tuo database. Non sappiamo cosa sia, quindi possiamo solo aiutare così tanto. – wuputah

4

Se stai inserendo un tavolo in grandi scoppi densi, potrebbe essere necessario un po 'di tempo per le pulizie, ad es. allocare più spazio per la tabella e gli indici.

Se non vuoi che la tua app aspetti, prova a usare INSERT DELAYED sebbene abbia i suoi lati negativi.

+4

INSERTO RITARDATO sembra essere una buona soluzione per il problema, ma non funziona su InnoDB :( – kalkin

+0

È anche deprecato in 5.6.6 e rimosso in 5.7. – TJChambers

12

ci sono 277259 file e solo alcuni inserti sono lenti (raro)

Ogni volta che una pagina B-Tree è piena, ha bisogno di essere diviso, che richiede un certo tempo. Inserire le prestazioni è anche più lento più indici hai, dato che ogni inserimento aggiorna tutti gli indici. 9000 ha già dichiarato correttamente che il tuo indice (timestamp, staff) copre l'indice (timestamp) nel 95% dei casi, ci sono casi molto rari quando sarà richiesto un indice a colonna singola (timestamp) per prestazioni migliori.

Ci sono anche alcune attività di background periodico che possono occasionalmente rallentare un inserto o due nel corso della giornata.

Inoltre, un altro motivo per i ritardi è semplicemente l'attività del database. Se si dispone di transazioni che bloccano le pagine che l'inserto deve aggiornare (o suddiviso in pagine), l'inserimento deve attendere fino a quando i blocchi di scrittura non vengono accettati. Queste altre attività non hanno nemmeno bisogno di avviare effettivamente una transazione, e non devono nemmeno essere contesa read-read; puoi anche avere contesa scrittura-scrittura o una coda creata da attività pesanti.

E l'ultimo motivo possibile: il server del database ha esaurito le risorse, che si tratti di memoria, CPU o I/O di rete. C'è solo così tanto che un server può fare, quindi dovrà aspettare finché non avrà abbastanza risorse.

+0

I caduto l'indice timestamp vedremo se gli inserti lenti svaniranno .. – kalkin

+0

@kalkin -.. è un fattore come indicato in precedenza, ma non l'unico * * una rimozione da solo sarà * non * fare gli inserti lento svanire, ma è certamente una buona idea. I motori di memorizzazione come InnoDB hanno attività in background che possono periodicamente rallentare un inserto o due. Altri fattori come backup automatici (MySQL), istantanee full-immagine (backup server), pagina crepe ecc possono anche causare rari ritardi . – RichardTheKiwi

+0

la maggior parte dei ritardi di inserimento sono quando c'è una sacco di traffico nel nostro "ora di punta" sulla pagina – kalkin

1

Se vi capita di essere di nuovo a livello sulla vostra installazione di MySQL, abbiamo notato un sacco di quella sorta di lentezza quando si utilizza la versione 4.1.