Recibimos datos de GPS en tiempo real a una velocidad de alrededor de 5000 pr. minuto (de 4 servidores TCP). Cada servidor usa una única conexión para insertar los datos y almacena los datos entre inserciones. Cada 15 minutos más o menos, un servicio obtiene estos datos y los procesa en viajes. Una vez que se han generado los viajes, los datos reales del GPS generalmente no son tan importantes, solo si el usuario desea ver la ruta en un mapa.
El problema es que parece que la base de datos está luchando para mantenerse al día con la velocidad de los datos que se insertan. A veces, cuando aumenta la carga, el tiempo de inserción aumenta repentinamente drásticamente (> 30 segundos), lo que a su vez permite que se almacenen más datos, lo que a su vez da como resultado inserciones más grandes y una mayor duración de inserción.
Espero recibir algunos comentarios sobre el diseño actual, y algunas de las ideas que tenemos para mejorar el rendimiento, y respuestas a algunas de nuestras preguntas, ¡y cualquier otro consejo que la gente pueda tener!
Diseño actual
Los datos están actualmente separados en tablas que representan una semana, y los datos de más de un año se archivan en una base de datos secundaria. Todo se une en una vista editable, que se utiliza tanto para inserciones como para lecturas.
Diseño de la mesa
- Id (PK, identificador único)
- DeviceId (FK, int)
- PersonId (FK, int)
- VehicleId (FK, int)
- TokenId (FK, int)
- UtcTime (PK, datetime2 (3))
- Latitud (flotante)
- Longitud (flotante)
- Velocidad (smallint)
- Encabezado (smallint)
- Satélites (tinyint)
- IOData (varbinary (100))
- IgnitionState (tinyint)
- Entrada de usuario (tinyint)
- CreateTimeUtc (datetime2 (3))
Índices
- DeviceId_CreateTimeUtc_Desc
- DeviceId_UtcTime_Desc (agrupado)
- PersonId_UtcTime_Desc
- TokenId_UtcTime_Desc
- VehicleId_UtcTime_Desc
Cada semana actualmente ocupa alrededor de 10 GB, incluidos los índices, y actualmente hay alrededor de 300 GB de datos en la base de datos principal.
Las tablas de datos en la base de datos principal tienen su propio grupo de archivos con 1 archivo, pero está en el mismo disco que todas las otras tablas en la base de datos principal. La base de datos secundaria está en un disco diferente, pero en la misma máquina.
Creo que también estamos ejecutando un trabajo de reconstrucción de índice semanalmente, cuando se usa una nueva partición de tabla (semana). No se realiza contracción.
La máquina es una HP de 8 núcleos con 12 GB de memoria, y el disco que contiene la base de datos principal ejecuta RAID 10.
Ideas
- Limite la cantidad de datos almacenados en la base de datos primaria a, por ejemplo, un máximo de 1 mes. Como mínimo, haría que la base de datos sea más manejable para la copia de seguridad / restauración, pero ¿podríamos esperar ver una mejora en el rendimiento al hacer esto?
- Cree 2 archivos en el grupo de archivos para los datos actuales y distribúyalos en 2 particiones físicas diferentes
- Cree bases de datos maestro-esclavo que contengan datos actuales, de modo que las inserciones y lecturas se realicen en diferentes bases de datos.
- Coloque archivos para datos actuales en discos SSD (¿la duplicación haría alguna diferencia de rendimiento con los discos SSD?)
Avíseme si necesita más información. Hay terriblemente muchos factores que influyen en el rendimiento, y probablemente igualmente muchas formas de modificarlo.