2013-05-14 19 views
6

Ho dati che sono una matrice di valori interi che indicano una curva di distribuzione a bande. Sto ottimizzando le prestazioni SELECT sulle prestazioni INSERT. Ci sono max 100 bande. Principalmente interrogherò questi dati sommando o facendo una media delle bande in un periodo di tempo.La denormalizzazione di righe su colonne migliora le prestazioni in SQL Server?

La mia domanda è possibile raggiungere prestazioni migliori appiattendo questi dati su una tabella con 1 colonna per ogni banda o utilizzando una singola colonna che rappresenta il valore della banda?

dati appiattiti

UserId ActivityId DateValue Band1 Band2 Band3....Band100 
10001 10002  1/1/2013 1  5  100  200 

o normalizzata

UserId ActivityId DateValue Band BandValue 
10001 10002  1/1/2013 1 1 
10001 10002  1/1/2013 2 5 
10001 10002  1/1/2013 3 100 

interrogazione Esempio

SELECT AVG(Band1), AVG(Band2), AVG(Band3)...AVG(Band100) 
FROM ActivityBands 
GROUP BY UserId 
WHERE DateValue > '1/1/2012' AND DateValue < '1/1/2013' 

risposta

8

Memorizzare i dati nel formato normalizzato.

Se non si ottengono prestazioni accettabili da questo schema, invece di denormalizzare, considerare prima quali indici si hanno sulla tabella. Probabilmente mancherai un indice che lo renderebbe simile alla tabella denormalizzata. Successivamente, prova a scrivere una query per recuperare i dati dalla tabella normalizzata in modo che il set di risultati assomigli alla tabella denormalizzata e utilizzi quella query per creare uno indexed view. Questo ti consentirà di selezionare prestazioni identiche a quelle della tabella denormalizzata, ma conserverà i vantaggi di una corretta normalizzazione per l'organizzazione dei dati.

1

Se si desidera recuperare i dati molto veloce allora si dovrebbe appiattirsi gli indici della tabella e utilizzare per migliorare la selezione su un ampio intervallo di colonne simile a quello che hai proposto. Tuttavia, se sei interessato a creare dati per aggiornamenti rapidi, utilizzare la normalizzazione di 3 ° o 4 ° livello in combinazione con molti join di tabelle dovrebbe offrire prestazioni migliori.

2

Se si accede a tutte (o la maggior parte) delle bande in ogni riga, la forma denormalizzata è migliore. Molto meglio nella mia esperienza.

Il motivo è semplice. La dimensione dei dati nelle pagine è molto più piccola, quindi è necessario leggere molte meno pagine per soddisfare la query. Il sovraccarico per la memorizzazione di una banda per riga è di circa 4 numeri interi o 32 byte. Quindi, 100 bande sono circa 3200 byte. All'interno di un singolo record, la dimensione del record è 100 * 4 + 8 o circa 408 byte. Se la query sta leggendo un numero significativo di record, ciò riduce significativamente i requisiti di I/O.

C'è un avvertimento. Se stai leggendo solo un record, allora 100 record si adattano a una singola pagina in SQL e un record si adatta a una singola pagina. L'I/O per una singola pagina può essere identico nei due casi. Il vantaggio sorge leggendo sempre più dati.

La tua query di esempio sta leggendo centinaia o migliaia di righe, quindi la denormalizzazione dovrebbe avvantaggiare una tale query.

4

La denormalizzazione consente di ottimizzare esattamente un mezzo per accedere ai dati, a spese di (quasi tutti) gli altri.

Se si dispone di un solo metodo di accesso che è critico per le prestazioni, è probabile che la denormalizzazione sia di aiuto; sebbene una corretta selezione dell'indice sia di maggior beneficio. Tuttavia, se si dispone di più percorsi di accesso critici per le prestazioni ai dati, è meglio cercare altre ottimizzazioni.

Creazione di un indice cluster appropriato; mettendo gli indici non in cluster su SSD. aumentando la memoria sul tuo server; sono tutte tecniche che miglioreranno le prestazioni per tutti gli accessi *, piuttosto che il trading tra vari accessi.