2012-03-09 24 views
5

Possiedo un'applicazione PHP/MySql in rapida crescita e con scrittura che inserisce nuove righe a una velocità di circa una dozzina al secondo in una tabella INNODB di diverse milioni di righe.MySql INSERTO vs PHP file_put_contents

Ho iniziato a utilizzare le istruzioni INSERT in tempo reale e poi ho spostato in PHP file_put_contents per scrivere le voci in un file e LOAD DATA INFILE per ottenere i dati nel database. Qual è l'approccio migliore?

Ci sono delle alternative che dovrei considerare? Come posso aspettarmi che i due metodi gestiscano le collisioni e aumentino il carico in futuro?

Grazie!

+0

Un'alternativa è scrivere su una tabella secondaria, quindi fare un grosso 'inserimento in ... selezionare da' sulla tabella principale, se le scritture sulla tabella principale stanno diventando un problema. –

risposta

3

Pensa a LOAD DATA INFILE come metodo batch di inserimento dati. Elimina il sovraccarico di accendere una query di inserimento per ogni istruzione, quindi è molto più veloce. Tuttavia, si perde parte del controllo durante la gestione degli errori. È molto più semplice gestire un errore su una singola query di inserimento o una riga nel mezzo di un file.

+0

È possibile utilizzare l'inserimento della sintassi nei valori della tabella (riga1), (riga2), ..., (rigaN); inserire tutte le righe che vuoi con una singola query. È anche possibile aggiungere "... sull'aggiornamento della chiave duplicata ..." per specificare come gestire le collisioni di chiavi univoche – atxdba

+0

@atxdba Questa è un'idea orribile su inserti di grandi dimensioni. – feketegy

+0

@feketegy Orribile come? Prestazione? http://tinyurl.com/7jmzbcp È SO post che spiega come è meglio e preferito. Certo, non si vuole caricare diversi concerti di dati in un singolo inserto, ma fare una dichiarazione indefinita sul fatto che è orribile che sia semplicemente sbagliato. Persino mysqldump creerà inserimenti batch per impostazione predefinita. Se stai dicendo che i dati di caricamento dei dati possono essere molto voluminosi, non posso dirlo. Stavo solo sottolineando la sintassi disponibile. – atxdba

0

Il modo in cui gestiamo i nostri inserti è quello di inviarli a un sistema di messaggi in coda come ActiveMQ. Da lì abbiamo un'applicazione separata che carica gli inserti utilizzando LOAD DATA INFILE in batch di circa 5000. La gestione degli errori può ancora aver luogo con l'infile, tuttavia elabora gli inserti molto più velocemente. Se l'impostazione di una coda di messaggi non rientra nell'ambito dell'applicazione, non vi è alcun motivo per cui file_put_contents non sia un'opzione accettabile, specialmente se è già implementata e funziona correttamente.

Inoltre, è possibile testare gli indici di disabilitazione durante le scritture per vedere se ciò migliora le prestazioni.

+0

Buona nota su come disabilitare gli indici - grazie – user1259956

+0

Un altro punto da considerare è dove si trova il collo di bottiglia per il tuo particolare sistema. Prova a utilizzare iostat e vmstat per determinare dove sono i tuoi rallentamenti e dove concentrare i tuoi sforzi. A seconda di ciò che stai facendo con i tuoi dati ci sono molte soluzioni per l'archiviazione, alcune delle quali molto più veloci se non come ACID friendly. – RumpRanger

0

Non sembra che dovresti usare innoDB. Indipendentemente da ciò, una dozzina di inserti al secondo non dovrebbe essere problematica nemmeno per l'hardware crappy - a meno che, forse, il tuo modello di dati sia molto complesso, ma per questo, LOAD DATA INFILE è molto buono perché, tra le altre cose, ricostruisce gli indici una sola volta, al contrario di ogni inserto. Quindi usare i file è un approccio decente, ma assicurati di aprirli in modalità solo aggiunta.

a lungo termine (1k + di scritture/s), consultare altri database, in particolare cassandra per applicazioni di scrittura pesanti.

+0

Anche l'indicizzazione era nella mia mente. Quale sarà più veloce per scrittura - aggiungendo un file piatto o inserendolo in un database? Come gestiscono richieste concorrenti? – user1259956

+0

dipende davvero, è necessario eseguire test e capire per il proprio ambiente. L'accodamento a un file è solo atomico se si mantengono i dati entro un limite (credo che sia 4K in linux), o si avranno problemi con la concorrenza – miki

2

A seconda che si possa permettere che i dati inseriti da PHP non siano immediatamente disponibili nella tabella, allora l'opzione INSERT DELAYED potrebbe essere un'opzione.

MySQL accetterà i dati da inserire e tratterà l'inserimento in seguito, mettendolo in coda. Quindi questo non bloccherà la tua applicazione PHP mentre MySQL garantisce che i dati vengano inseriti in seguito.

As it says in the manual:

Un altro grande vantaggio di utilizzare INSERT DELAYED è che gli inserti da molti clienti sono raggruppati e scritti in un unico blocco. Questo è molto più veloce di molti inserti separati.

Ho usato questo per i dati di registrazione in cui una perdita di dati non è fatale, ma se volete essere protetti da crash del server quando i dati provenienti da INSERT DELAYED non erano stati ancora inserito, si poteva guardare in replicare le modifiche via per una macchina slave dedicata.

0

se si esegue la procedura di inserimento sql, eseguire il wrapping delle istruzioni di esecuzione pdo in una transazione. farlo accelererebbe notevolmente il processo.

Problemi correlati