MySQL ad alte prestazioni per molti SELECT / INSERT / UPDATE / DELETEs


9

Sto creando un modulo in cui ogni utente ottiene spesso un record in una tabella da 10 a 300 secondi.

Allo scadere del tempo, un record viene eliminato. Il caso è: ci saranno molti utenti e i record cambieranno molto spesso - in che modo ciò influirà sulle prestazioni dell'applicazione per questa tabella, perché i record cambieranno molto spesso e mi chiedo se mysql vada bene? Come gli indici vanno e vengono, i dati cambiano come 200 volte / secondi per questa particolare tabella. Forse sto scegliendo una cattiva soluzione per questo tipo di lavoro. Eventuali suggerimenti ?

Grazie!


2
Hai provato a memorizzare i dati in memcache e quindi a svuotarli in una transazione ogni pochi secondi?

3
"i dati cambiano come 200 volte / secondi per questa particolare tabella" Penso che la riga che spiega questi dati dovrebbe essere mantenuta in memoria, la durata per cui deve persistere è minuscola, quindi probabilmente non dovrebbe andare sul disco?

Gli indici vanno e vengono? Non riesco a pensare a nessun motivo per cui dovresti creare e rilasciare indici molto spesso.
Barry Brown,

Risposte:


3

Una cosa da prendere in considerazione è il modo in cui MySQL utilizza i buffer per i suoi principali motori di archiviazione: InnoDB e MyISAM .

Ciò che si trova nella memoria differisce notevolmente tra questi motori di archiviazione.

InnoDB memorizza nella cache sia le pagine dei dati che quelle dell'indice. Vengono caricati nel pool di buffer InnoDB, che viene ridimensionato da innodb_buffer_pool_size .

MyISAM memorizza nella cache solo le pagine di indice e vengono caricate nella Key Cache (Key Buffer), che è dimensionato da key_buffer_size .

È necessario utilizzare information_schema.tables per ottenere le dimensioni dei dati e dell'indice occupate sul disco per dimensionare correttamente il pool di buffer InnoDB e la cache delle chiavi MyISAM .

A seconda di quanti dati hai e di quanto tempo concederai, puoi riscaldare le cache come segue:

Per ogni tavolo TableT

  • vai a ciascun indice NDX
  • per ogni indice NDX
    • eseguire SELECT ogni colonna in NDX, almeno una colonna non indicizzata in TableT da TableT

In questo modo garantisci che ogni pagina di dati e indice venga letta almeno una volta. Si siederanno nella cache. Questo concetto è praticato, in parte e in linea di principio, da Percona . Percona ha sviluppato questo concetto in mk-slave-prefetch . Ciò che fa questo programma è

  • leggere i log di inoltro su uno slave prima che lo slave elabori l'SQL in esso
  • prendere un'istruzione SQL dal registro di inoltro e convertirla in un SELECT utilizzando le clausole WHERE, GROUP BY e ORDER BY come guida per la scelta degli indici
  • eseguire l'istruzione SELECT proveniente da SQL convertito

Ciò forza lo slave ad avere il 99,99% dei dati necessari allo slave per elaborare rapidamente l'SQL. Ciò inoltre rende lo slave preparato nel caso in cui si esegua il failover manuale dello slave e lo promuova a un master, QUALI SONO LE STRADE SOLO SULLA STESSA QUELLA DEL MASTER DA CUI SEI ERRATO.

CONCLUSIONE

Non c'è niente di meglio che avere cache pronte, disponibili e in grado di utilizzarle in un ambiente con INSERTI, AGGIORNAMENTI ed ELIMINI pesanti.

Provaci !!!

AVVERTIMENTO

Con la nascita di prodotti come memcached, alcuni si sono allontanati dalla necessità di eseguire la corretta messa a punto di MySQL. Certo, molti siti beneficiano della spinta nel recupero dei dati fornita controllando il comportamento della memorizzazione nella cache dei dati come gli sviluppatori hanno visto rapidamente con memcached. Molti altri siti, semplicemente cambiando i motori di archiviazione o configurando correttamente MySQL, hanno realizzato gli stessi vantaggi in termini di prestazioni. Prima di rinunciare al database e utilizzarlo rigorosamente come repository, sfruttare al massimo il database. Segui la dovuta diligenza e potresti essere piacevolmente sorpreso da ciò che MySQL farà per te.


5

Se questa è una cattiva soluzione dipenderebbe da molte cose. Questi dati devono essere persistenti? Altrimenti forse una soluzione che mantiene semplicemente questi dati in memoria funzionerebbe meglio.

"Molti utenti" non stanno davvero aiutando nessuno. Molto probabilmente MySQL andrà bene se "molto" significherebbe alcune centinaia. (Anche se dipende da cos'altro deve gestire il tuo database. Molto probabilmente dovrebbero funzionare anche diverse migliaia.)

Dopotutto, non importa molto, se scrivi quei record per rimanere o eliminarli dopo pochi secondi o minuti. L'eliminazione fa solo due operazioni su una. E MySQL può sicuramente gestire una grande quantità di creazione ed eliminazione di record. Assicurati di utilizzare un semplice indice per trovare nuovamente quei record per l'eliminazione.

Ma senza numeri reali e alcune informazioni sull'hardware utilizzato dal server di database, non è possibile rispondere con molta precisione.

La cosa migliore sarebbe scrivere qualche piccola applicazione, che simula semplicemente la quantità di carico che pensi di ottenere senza fare molta elaborazione reale, basta rilasciare molti record sul server, eliminarli, alla stessa velocità eseguire alcune query come la il resto del programma verrebbe generato. Dai un'occhiata al tuo server e vedi se questo lo influenza in qualche modo.

Non sono sicuro, ma ci sono opzioni da impostare per MySQL che gli permetterebbero di memorizzare nella cache completamente una tabella, lo fa comunque in molte situazioni e molto probabilmente non dovrai cambiare molto. Ma se parli di un numero davvero elevato di utenti e record, puoi forse modificare alcuni parametri per ottimizzare la memorizzazione nella cache per le tue esigenze speciali.


4
+1 per suggerire una soluzione che mantiene i dati in memoria.

3

Ecco un'idea folle . Implica ipotesi e pratiche non sempre consigliate (come l'aggiornamento di una chiave) - Avrò molti aspetti negativi per averlo suggerito, ma qui va ...

Supponendo di avere un volume molto elevato di righe e un elevato volume di eliminazioni, è possibile migliorare le prestazioni di eliminazione creando 2 partizioni sulla tabella. Le partizioni differirebbero per la prima cifra della chiave. Esempio:

Il valore chiave 1123234441 è per le righe attive e il valore chiave: 9123234441 è per le righe inattive (la prima cifra in questo esempio viene utilizzata come segue: 1 = attivo, 9 = inattivo).

Ora quando l'utente elimina una riga, non si elimina fisicamente la riga, si aggiorna la chiave (Ahi!), Questo sposta automaticamente la riga nella partizione di righe inattive.

Naturalmente, è necessario limitare le selezioni per leggere i dati solo dalla partizione attiva. Ora la parte interessante è che eliminare la partizione di righe inattive è estremamente rapido.

Come ho detto prima, questo funziona se hai solo 1 tabella. Non l'ho testato, quindi è solo un approccio teorico ma ho sperimentato la velocità di caduta della partizione ed è incredibilmente veloce.

Per migliorare le selezioni, utilizzare l'indicizzazione corretta e migliorare gli inserti minimizzare le dimensioni della riga e il numero di indici (questa affermazione è molto generica ...)

Per un riferimento, consultare: http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html Spero che questo aiuti.


2
Non sono sicuro, se questo ha senso per questo specifico problema (la mia ipotesi è ancora, che mysql memorizzerà tutto nella cache e molto probabilmente quei record non vedranno mai vedere un disco). Ma +1 per aver messo in evidenza un'interessante tecnica di ottimizzazione che non conoscevo ormai.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.