massiccio tavolo nel database SQL 2005 ha bisogno di una migliore performance!
-
19-09-2019 - |
Domanda
Sto lavorando su un data guidato un'applicazione web che utilizza un database SQL 2005 (edizione standard).
Una delle tabelle è piuttosto grande (8 milioni + file di grandi dimensioni con circa 30 colonne). La dimensione della tabella di effetti, ovviamente, le prestazioni del sito web che è la selezione degli elementi della tabella tramite stored procedure. La tabella è indicizzata ma la prestazione è scarsa a causa della enorme quantità di righe della tabella - questo è parte del problema - la tabella è altrettanto letta come aggiornato, quindi non possiamo aggiungere / rimuovere indici senza fare uno le operazioni di peggio.
L'obiettivo che ho qui è quello di aumentare le prestazioni durante la selezione delle voci dalla tabella. Il tavolo ha dati 'corrente' e dati vecchi / appena sfiorati. La soluzione più efficace che possiamo pensare, in questa fase è quello di separare la tabella in 2, vale a dire, uno per gli oggetti vecchi (prima di una certa data, dicono 1 gennaio 2005) e uno per gli oggetti più recenti (uguale o prima del 1 gennaio 2005) .
Siamo a conoscenza di cose come viste partizionate distribuite - ma tutte queste caratteristiche richiedono Enterprise Edition, che il cliente non comprerà (e no, gettando hardware le cose è non accadrà neanche)
.Soluzione
Si può sempre roll your own "partizionamento / DPV dei poveri", anche se non l'odore come il modo giusto per farlo. Questo è solo un ampio approccio concettuale:
-
Creare una nuova tabella per i dati dell'anno in corso - stessa struttura, stessi indici. Regolare la stored procedure che scrive il, grande tavolo principale per scrivere a entrambe le tabelle (solo temporaneamente). Mi consiglia di effettuare la logica nella stored procedure dire se CURRENT_TIMESTAMP> = '[una data tutta senza il tempo]' - questo renderà più facile per riempire i dati di questa tabella che precede la modifica della procedura che l'archiviazione lì.
-
Creare una nuova tabella per ogni anno nella vostra storia utilizzando SELECT INTO dalla tabella principale. È possibile farlo in un database diverso nella stessa istanza per evitare il sovraccarico nel database corrente. I dati storici non sta per cambiare Presumo, quindi in questo altro database si potrebbe anche rendere più letto solo quando è fatto (che sarà notevolmente migliorare le prestazioni in lettura).
-
Una volta che avete una copia di tutta la tabella, è possibile creare le viste che fanno riferimento proprio l'anno in corso, un'altra vista che fa riferimento 2005 per l'anno in corso (utilizzando UNION ALL tra la tabella corrente e quelle degli altri database che sono> = 2005), e un altro che fa riferimento a tutte le tre serie di tabelle (quelli citati, e le tabelle che pre-data 2005). Naturalmente è possibile rompere questo ancora di più ma ho voluto solo per mantenere il concetto di minimal.
-
Modificare le stored procedure che leggono i dati di essere "più intelligenti" - se l'intervallo di date richiesto cade entro l'anno solare in corso, utilizzare la più piccola vista che è solo locali; se l'intervallo di date è> = 2.005 quindi utilizzare il secondo punto di vista, altrimenti utilizzare il terzo punto di vista. È possibile seguire la logica simile con le stored procedure che scrivono, se si sta facendo più di un semplice inserimento di nuovi dati che è rilevante solo per l'anno in corso.
-
A questo punto si dovrebbe essere in grado di fermare l'inserimento nella tabella massiccia e, una volta che tutto è dimostrato di funzionare, cadere e recuperare un po 'di spazio su disco (e con questo intendo dire liberando spazio nel file di dati (s) per il riutilizzo, non l'esecuzione di un db strizzacervelli -. dal momento che si intende utilizzare quello spazio di nuovo)
Non ho tutti i dettagli della vostra situazione, ma si prega di seguire se avete domande o dubbi. Ho usato questo approccio in diversi progetti di migrazione tra cui uno che sta succedendo in questo momento.
Altri suggerimenti
prestazione è scarsa a causa della enorme quantità di righe della tabella
8 milioni di righe non suona tutto quel pazzo. Hai controllato i vostri piani di query?
la tabella è altrettanto letta come aggiornato
Stai in realtà aggiornando una colonna indicizzata o è altrettanto leggere e inserito per
(e no, gettando hardware le cose è non accadrà neanche)
Questo è un peccato, perché la RAM è sporcizia a buon mercato.