Domanda

Ho un grande database normalizzato i dati dell'ordine che sta diventando molto lento query per la creazione di.Molte delle query che uso io in rapporti di unirti a cinque o sei tavoli e si trovano a dover esaminare decine o centinaia di migliaia di righe.

Ci sono un sacco di domande e di più sono stati ottimizzati, per quanto possibile per ridurre il carico del server e aumentare la velocità.Penso che è il momento di iniziare a mantenere una copia dei dati in un denormalizzato formato.

Tutte le idee su un approccio?Devo iniziare con un paio di miei peggiori query e passare da lì?

È stato utile?

Soluzione

Io so di più su mssql che mysql, ma non credo che il numero di join o il numero di righe che si sta parlando dovrebbe causare troppi problemi con gli indici corretti in luogo.Hai analizzato il piano di query per vedere se manca qualsiasi?

http://dev.mysql.com/doc/refman/5.0/en/explain.html

Detto questo, una volta che si sono adempiute le finalità prefissate, con gli indici e hanno esaurito tutte le altre possibilità, de-normalizzazione potrebbe essere la risposta giusta.Se solo uno o due query che sono problemi, un approccio manuale è probabilmente adeguato, mentre una sorta di data warehousing strumento di potrebbe essere migliore per la creazione di una piattaforma per sviluppare cubi di dati.

Ecco un sito che ho trovato che tocca l'argomento:

http://www.meansandends.com/mysql-data-warehouse/?link_body%2Fbody=%7Bincl%3AAggregation%7D

Ecco una tecnica semplice che è possibile utilizzare per mantenere la denormalizzazione query semplice, se si sta solo facendo un po ' alla volta (e non ho intenzione di sostituire il vostro OLTP tabelle, solo la creazione di uno nuovo per scopi di reporting).Supponiamo di avere questa query nell'applicazione:

select a.name, b.address from tbla a 
join tblb b on b.fk_a_id = a.id where a.id=1

Si potrebbe creare una tabella denormalizzata e popolare con quasi la stessa query:

create table tbl_ab (a_id, a_name, b_address); 
-- (types elided)

Notare la sottolineatura partita l'alias di tabella si utilizza

insert tbl_ab select a.id, a.name, b.address from tbla a
join tblb b on b.fk_a_id = a.id 
-- no where clause because you want everything

Quindi per risolvere il tuo app per utilizzare la nuova tabella denormalizzata, passare i punti per caratteri di sottolineatura.

select a_name as name, b_address as address 
from tbl_ab where a_id = 1;

Per enorme query questo può risparmiare un sacco di tempo e rende chiara l'origine dei dati, ed è possibile ri-utilizzare le query che hai già.

Ricordate, sto solo sostenendo questo come ultima risorsa.Scommetto che ci sono un paio di indici che consentono di.E quando si de-normalizzare, non dimenticate di considerare lo spazio sui dischi, e capire quando si esegue la query per popolare le nuove tabelle.Questo probabilmente dovrebbe essere la notte, o quando l'attività è bassa.E i dati in tabella, di certo, non potrà mai essere esattamente fino a data.

[Ancora un altro edit] non dimenticare che le nuove tabelle devono essere indicizzate troppo!La parte buona è che si è in grado di indicizzare al contenuto del vostro cuore e di non preoccuparsi di blocco di aggiornamento contesa, perché, indipendentemente dalla vostra massa inserire la tabella sarà solo vedere seleziona.

Altri suggerimenti

MySQL 5 non supporta vista, che può essere utile in questo scenario.Suona come hai già fatto un sacco di ottimizzazione, ma se non si può usare MySQL SPIEGARE la sintassi per vedere ciò che gli indici vengono effettivamente utilizzati e ciò che sta rallentando le vostre domande.

Come lontano come andare circa la normalizzazione dei dati (se si utilizza vista o solo la duplicazione dei dati in maniera più efficiente), penso di iniziare con il più lento di query e di lavoro il vostro senso attraverso è un buon approccio.

So che questo è un po ' di tangenziale, ma hai provato a vedere se ci sono più gli indici si può aggiungere?

Non ho un sacco di DB sfondo, ma io lavoro con i database molto di recente, e ho scoperto che un sacco di query può essere migliorata con l'aggiunta di indici.

Stiamo usando DB2, e c'è un comando chiamato db2expln e db2advis, il primo indica se l'analisi della tabella vs indice scansioni vengono utilizzati, e la seconda si consiglia di indici è possibile aggiungere per migliorare le prestazioni.Sono sicuro che MySQL ha strumenti simili...

Comunque, se questo è qualcosa che non hai considerato, ancora, non ha aiutato molto con me...ma se hai già seguito questa strada, quindi credo che non è quello che state cercando.

Un'altra possibilità è una "vista materializzata" (o come la chiamano in DB2), che consente di specificare una tabella che è essenzialmente costruito delle parti da più tabelle.Così, invece di normalizzare le colonne reali, è possibile fornire questo punto di vista per accedere ai dati...ma non so se questo è grave impatto sulle prestazioni di inserimenti/aggiornamenti/elimina, ma se si è "materializzata", quindi dovrebbe aiutare con seleziona dato che i valori sono fisicamente memorizzati separatamente).

In linea con alcuni degli altri commenti, mi sarebbe sicuramente guardare la tua indicizzazione.

Una cosa che ho scoperto all'inizio di quest'anno nel nostro database MySQL stato il potere di indici compositi.Per esempio, se si stanno segnalando in ordine di numero, nel corso di intervalli di date, un indice composito il numero d'ordine e data ordine di colonne, potrebbero aiutare.Credo che MySQL può utilizzare solo un indice per la query in modo che se avete appena avuto indici separati il numero d'ordine e data ordine avrebbe dovuto decidere solo uno di loro di utilizzare.Utilizzando il comando explain può aiutare a determinare questo.

Per dare un'indicazione della performance con buoni indici (tra cui numerosi indici compositi), sono in grado di eseguire query di entrare in 3 tavoli nel nostro database e ottenere i risultati istantaneamente nella maggior parte dei casi.Per di più complesso di reporting la maggior parte delle query eseguite in meno di 10 secondi.Queste 3 tabelle sono 33 milioni di euro, di cui 110 milioni e 140 milioni di righe, rispettivamente.Nota che abbiamo avuto anche già normalizzati un po ' di accelerare i nostri più comuni query sul database.

Maggiori informazioni riguardo le tabelle e i tipi di query di creazione di report può consentire ulteriori suggerimenti.

Per MySQL mi piace questo discorso: Mondo Reale Web:Prestazioni E Scalabilità, MySQL Edizione.Questo contiene un sacco di pezzi diversi di consigli per ottenere di più la velocità di MySQL.

Si potrebbe anche prendere in considerazione la scelta in una tabella temporanea e quindi l'esecuzione di query su quella tabella temporanea.Questo permetterebbe di evitare la necessità di ricongiungersi con le tabelle per ogni singola query è problema (supponendo che si può utilizzare la tabella temporanea per le numerose domande, ovviamente).Questo fondamentalmente si dà denormalizzato dati, ma se si sta solo facendo selezionare le chiamate, non c'è nessuna preoccupazione circa la coerenza dei dati.

Ulteriormente per la mia risposta precedente, un altro approccio che abbiamo preso in alcune situazioni è quello di memorizzare chiave di reporting di dati in distinte tabelle di sintesi.Ci sono alcune query di creazione di report che sono solo andando a essere lento anche dopo denormalising e ottimizzazioni e abbiamo scoperto che la creazione di una tabella e la memorizzazione di esecuzione totale o informazioni di riepilogo per tutto il mese come è arrivata in fatto la fine del mese di segnalazione, molto più veloce di così.

Abbiamo trovato questo approccio facile da attuare in quanto non rompere nulla, che era già al lavoro - è solo un database aggiuntivo con inserti in alcuni punti.

Ho giocato con indici compositi e ho visto alcuni vantaggi reali...forse sarò l'installazione di alcuni test per vedere se è possibile salvare qui..almeno per un po ' di più.

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