Riceviamo dati GPS in tempo reale a una velocità di circa 5000 pr. minuto (da 4 server TCP). Ogni server utilizza una singola connessione per inserire i dati e li inserisce nel buffer tra gli inserti. Ogni 15 minuti circa un servizio recupera questi dati e li trasforma in viaggi. Una volta che i viaggi sono stati generati, i dati GPS effettivi di solito non sono così importanti, solo se l'utente vuole vedere il percorso su una mappa.
Il problema è che sembra che il database stia lottando per tenere il passo con la velocità di inserimento dei dati. A volte quando il carico aumenta, il tempo di inserimento aumenta improvvisamente drasticamente (> 30 secondi), il che a sua volta consente di bufferizzare più dati, il che a sua volta si traduce in inserti più grandi e una durata degli inserti più lunga.
Spero di ottenere alcuni commenti sul design attuale e su alcune delle idee che dobbiamo migliorare per le prestazioni, e le risposte ad alcune delle nostre domande - e qualsiasi altro consiglio che la gente potrebbe avere!
Design attuale
I dati sono attualmente suddivisi in tabelle che rappresentano una settimana e i dati più vecchi di un anno vengono archiviati in un database secondario. Il tutto è unito in una vista modificabile, che viene utilizzata sia per gli inserti che per le letture.
Design del tavolo
- Id (PK, uniqueidentifier)
- DeviceId (FK, int)
- PersonId (FK, int)
- VehicleId (FK, int)
- TokenId (FK, int)
- UtcTime (PK, datetime2 (3))
- Latitudine (galleggiante)
- Longitudine (float)
- Velocità (piccola)
- Titolo (piccolo)
- Satelliti (tinyint)
- IOData (varbinary (100))
- IgnitionState (tinyint)
- UserInput (tinyint)
- CreateTimeUtc (datetime2 (3))
Indici
- DeviceId_CreateTimeUtc_Desc
- DeviceId_UtcTime_Desc (Clustered)
- PersonId_UtcTime_Desc
- TokenId_UtcTime_Desc
- VehicleId_UtcTime_Desc
Ogni settimana occupa attualmente circa 10 GB inclusi gli indici e attualmente ci sono circa 300 GB di dati nel database principale.
Le tabelle di dati nel database principale hanno il proprio filegroup con 1 file, ma si trova sullo stesso disco di tutte le altre tabelle nel database principale. Il database secondario si trova su un altro disco, ma sullo stesso computer.
Penso che stiamo anche eseguendo un processo di ricostruzione dell'indice settimanalmente, quando viene utilizzata una nuova partizione di tabella (settimana). Non viene eseguito alcun restringimento.
La macchina è un HP a 8 core con 12 GB di memoria e il disco che contiene il database principale esegue RAID 10.
idee
- Limitare la quantità di dati memorizzati nel database primario ad es. Al massimo 1 mese. Perlomeno renderebbe il database più gestibile per il backup / ripristino, ma potremmo aspettarci di vedere un miglioramento delle prestazioni in questo modo?
- Creare 2 file nel filegroup per i dati correnti e distribuirli su 2 diverse partizioni fisiche
- Crea database master-slave che contengono dati correnti, quindi inserimenti e letture vengono eseguiti su database diversi
- Inserisci i file per i dati correnti sui dischi SSD (il mirroring farebbe alcuna differenza nelle prestazioni con i dischi SSD?)
Per favore fatemi sapere se sono necessarie ulteriori informazioni. Ci sono orribilmente molti fattori che influenzano le prestazioni e probabilmente anche molti modi per modificarle.