2012-10-23 17 views
7

Ho una tabella di poco più di 1 miliardo di righe di dati di serie temporali con prestazioni di inserimento fantastiche ma (a volte) prestazioni di selezione terribili.SQL Server: prestazioni dei dati delle serie temporali

Tabella tblTrendDetails (PK è ordinato come mostrato):

PK TrendTime datetime 
PK CavityId  int 
PK TrendValueId int 
    TrendValue real 

La tabella viene continuamente tirando in nuovi dati e l'eliminazione dei vecchi dati, in modo da inserire ed eliminare prestazioni deve rimanere scattanti.

Quando si esegue una query come la seguente, prestazioni è povero (30 sec):

SELECT * 
FROM tblTrendDetails 
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime 
    AND CavityId = @inCavityId 
    AND TrendValueId = @inTrendId 

Se eseguo la stessa query nuovamente (con tempi simili, ma qualsiasi @inCavityId o @inTrendId), la prestazione è molto buono (1 secondo). I contatori delle prestazioni mostrano che l'accesso al disco è il colpevole la prima volta che viene eseguita la query.

Eventuali suggerimenti su come migliorare le prestazioni senza influire negativamente (significativamente) sull'inserimento o sull'eliminazione delle prestazioni? Qualsiasi suggerimento (incluso cambiare completamente il database sottostante) è benvenuto.

+1

Il PK è in cluster? Qualche indice? –

+1

@TimLehner Sì .. PK è in cluster. Nessun (altro) indice. – pilotcam

risposta

6

Il fatto che le query successive di dati uguali o simili siano eseguite molto più rapidamente è probabilmente dovuto a SQL Server caching your data. Detto questo, è possibile accelerare questa query iniziale?

Verificare il piano di query:

La mia ipotesi è che la query deve tradursi in un Index Seek piuttosto che un indice di scansione (o peggio, una scansione tabella). Si prega di verificare questo utilizzando SET SHOWPLAN_TEXT ON; o una funzionalità simile. Utilizzando between e = come la tua query dovrebbe davvero take advantage of the clustered index, anche se that's debatable.

Indice Frammentazione:

E 'possibile che il vostro indice cluster (la chiave primaria in questo caso) è molto frammentato, dopo tutti questi inserti ed elimina. Probabilmente controllerei questo con DBCC SHOWCONTIG (tblTrendDetails).

È possibile deframmentare gli indici della tabella con DBCC INDEXDEFRAG (MyDatabase, tblTrendDetails). Questo potrebbe richiedere un po 'di tempo, ma permetterà al tavolo di rimanere accessibile, e puoi interrompere l'operazione senza brutti effetti collaterali.

Potrebbe essere necessario andare oltre e utilizzare DBCC DBREINDEX (tblTrendDetails). Questa è un'operazione offline, quindi, dovresti farlo solo quando non è necessario accedere alla tabella.

Ci sono alcune differenze descritte qui: Microsoft SQL Server 2000 Index Defragmentation Best Practices.

Tenere presente che il registro delle transazioni può aumentare notevolmente dalla deframmentazione di una tabella di grandi dimensioni e può richiedere molto tempo.

viste partizionate:

Se questi non porre rimedio alla situazione (o la frammentazione non è un problema), si può anche desiderare di guardare a partitioned views, in cui si crea un gruppo di tabelle di base sottostanti per vari intervalli di record, quindi unirli tutti in una vista (sostituendo la tabella originale).

Meglio Stuff:

Se le prestazioni di questi seleziona è una reale necessità di business, si può essere in grado di fare il caso per una migliore hardware: le unità più veloci, più memoria, ecc Se le unità sono due volte più veloce, allora questa query verrà eseguita in metà tempo, sì? Inoltre, questo potrebbe non essere praticabile per te, ma ho semplicemente trovato le nuove versioni di SQL Server per essere veramente più veloce con più opzioni e meglio da mantenere. Sono felice di aver spostato la maggior parte dei dati della mia azienda in 2008R2. Ma sto divagando ...

+2

+1 per una risposta molto accurata e ben dichiarata. Avevo superato la verifica del piano di query prima di pubblicare la domanda. Ma non pensavo alla frammentazione dell'indice. Lo 'SHOWCONTIG' ha sicuramente rivelato la frammentazione. Sto facendo funzionare un 'INDEXDEFRAG' ora. – pilotcam

Problemi correlati