Tengo una aplicación de control de tiempos, que ha estado funcionando en el cliente durante unos dos años.
La aplicación dispone de un informe que ofrece un listado de "incidencias detectadas".
Se trata de Tareas que han quedado abiertas en días anteriores, u otras incidencias que haya que corregir.
La consulta es una consulta de union que agrupa los diferentes tipos de incidencia, es la siguiente:
Código SQL:
Ver original
SELECT A.Fecha AS Fecha, A.CodigoTrabajador AS CodigoTrabajador, T.Nombre AS NombreTrabajador, 'ASISTENCIA' AS TipoIncidencia, A.HoraInicio AS HoraInicio, 'No se ha cerrado la Asistencia' AS Descripcion FROM AsistenciasTrabajadores AS A INNER JOIN Trabajadores AS T ON A.CodigoTrabajador = T.CodigoTrabajador WHERE LEN(ISNULL(A.HoraFin, '')) = 0 AND A.Fecha<>@Fecha UNION SELECT P.Fecha AS Fecha, P.CodigoTrabajador AS CodigoTrabajador, T.Nombre AS NombreTrabajador, 'PARTE TRABAJO' AS TipoIncidencia, P.HoraInicio AS HoraInicio, 'No se ha cerrado el Parte | ' + L.CodigoOrdenProduccion + ' | ' + P.CodigoOperacion + ' - ' + L.NombreOperacion AS Descripcion FROM PartesTrabajo AS P INNER JOIN Trabajadores AS T ON P.CodigoTrabajador = T.CodigoTrabajador INNER JOIN LineasOrdenesProduccion AS L ON P.IdLineaOrdenProduccion = L.IdLineaOrdenProduccion WHERE LEN(ISNULL(P.HoraFin, '')) = 0 AND P.Fecha<>@Fecha UNION SELECT P.Fecha AS Fecha, P.CodigoTrabajador AS CodigoTrabajador, T.Nombre AS NombreTrabajador, 'PARTE TRABAJO' AS TipoIncidencia, P.HoraInicio AS HoraInicio, 'Parte cerrado fuera de tiempo | ' + L.CodigoOrdenProduccion + ' | ' + P.CodigoOperacion + ' - ' + L.NombreOperacion AS Descripcion FROM PartesTrabajo P INNER JOIN AsistenciasTrabajadores A ON P.CodigoTrabajador = A.CodigoTrabajador AND P.Fecha = A.Fecha INNER JOIN Trabajadores AS T ON P.CodigoTrabajador = T.CodigoTrabajador INNER JOIN LineasOrdenesProduccion AS L ON P.IdLineaOrdenProduccion = L.IdLineaOrdenProduccion WHERE CAST(P.HoraFin AS DateTime) NOT BETWEEN CAST(A.HoraInicio AS DateTime) AND CAST(A.HoraFin AS DateTime) AND CAST(P.HoraInicio AS DateTime) BETWEEN CAST(A.HoraInicio AS DateTime) AND CAST(A.HoraFin AS DateTime) AND CAST(P.HoraFin AS DateTime) > CAST(A.HoraFin AS DateTime) AND A.TipoAsistencia='A' UNION SELECT P.Fecha AS Fecha P.CodigoTrabajador AS CodigoTrabajador, T.Nombre AS NombreTrabajador, 'PARTE TRABAJO' AS TipoIncidencia, P.HoraInicio AS HoraInicio, 'Parte sin Asistencia | ' + L.CodigoOrdenProduccion + ' | ' + P.CodigoOperacion + ' - ' + L.NombreOperacion AS Descripcion FROM PartesTrabajo P INNER JOIN Trabajadores AS T ON P.CodigoTrabajador = T.CodigoTrabajador INNER JOIN LineasOrdenesProduccion AS L ON P.IdLineaOrdenProduccion = L.IdLineaOrdenProduccion LEFT JOIN AsistenciasTrabajadores A ON P.CodigoTrabajador = A.CodigoTrabajador AND P.Fecha = A.Fecha WHERE A.CodigoTrabajador IS NULL
El problema que me ocupa ahora, es que esta consulta ha comenzado a dar problemas de TimeOut.
Se que puedo aumentar el TimeOut a través del objeto SQLCommand de .NET que lanza la consulta.
Pero también he leído distintas opiniones que no aconsejan aumentar ese TimeOut, puesto que es mejor intentar "tunear" la consulta, aplicar índices, etc...
El motivo de este post es que, una vez revisada la consulta, puedan recomendarme las distintas acciones que crean convenientes.
Por ejemplo, tengo Primary Keys asignadas en cada tabla (lógicamente), y Foreign Keys, pero no existen otros índices.
Este es un resumen de las ForeignKeys:
Código SQL:
Ver original
LineasOrdenesProduccion > FOREIGN KEY [CodigoOrdenProduccion] REFERENCES OrdenesProduccion ([CodigoOrdenProduccion]) LineasOrdenesProduccion > FOREIGN KEY [CodigoOperacion] REFERENCES Operaciones ([CodigoOperacion]) PartesTrabajo > FOREIGN KEY [CodigoTrabajador] REFERENCES Trabajadores ([CodigoTrabajador]) PartesTrabajo > FOREIGN KEY [IdLineaOrdenProduccion] REFERENCES LineasOrdenesProduccion ([IdLineaOrdenProduccion]) AsistenciasTrabajadores > FOREIGN KEY [CodigoTrabajador] REFERENCES Trabajadores ([CodigoTrabajador])
No sé qué tan importantes serán los nuevos índices que me recomienden en la velocidad de esta consulta, pero les estaría muy agradecido si me dieran sus opiniones al respecto.
Qué indices ven más convenientes, cambios en la consulta, u otros aspectos que no esté teniendo en cuenta.
Gracias por su ayuda.
Saludos.