Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Mejorar el rendimiento del Stored

Estas en el tema de Mejorar el rendimiento del Stored en el foro de SQL Server en Foros del Web. Hola buenas tardes, tengo una aplicación donde los usuarios registran sus ausencias cada vez que falten al trabajo, estos datos se guardan en la tabla ...
  #1 (permalink)  
Antiguo 22/03/2017, 12:45
 
Fecha de Ingreso: agosto-2010
Mensajes: 126
Antigüedad: 14 años, 3 meses
Puntos: 9
Mejorar el rendimiento del Stored

Hola buenas tardes, tengo una aplicación donde los usuarios registran sus ausencias
cada vez que falten al trabajo, estos datos se guardan en la tabla Ausencia

Las tablas tienen los siguientes campos

Usuario
Id| Nombre| Legajo| Clave| Activo| Area_Id

Ausencia
Id| Usuario_Id| Observaciones| Fecha

Area
Id| Descripcion

Area: Sistema, Contabilidad, etc..

Hice un stored que muestra la cantidad de ausencias por mes que registraron los usuarios de las distintas Áreas, el stored recibe como parámetro el Id del Área y el año, entonces lo primero que hago es obtener todos los meses que tiene ese año para luego contar cuantas ausencias se registraron en ese mes.

El stored muestra el resultado que quiero, pero el tema es que es muy lento tarda mucha y en la tabla Ausencia solo tengo 40000 datos es poco para la lentitud, no se cómo mejorar el rendimiento de este stored.

Código SQL:
Ver original
  1. DECLARE @Area_Id INT
  2.     DECLARE @Anho    INT
  3.    
  4.     SET @Area_Id = 1
  5.     SET @Anho = 2017
  6.  
  7.     DECLARE @Meses TABLE
  8.     (
  9.         Mes INT    
  10.     )
  11.  
  12.     INSERT INTO @Meses
  13.            SELECT DISTINCT DATEPART(MONTH, A.Fecha)
  14.            FROM Ausencia A
  15.            WHERE DATEPART(YEAR, A.Fecha) = @Anho
  16.            ORDER BY DATEPART(MONTH, A.Fecha) ASC
  17.  
  18.     DECLARE @Mes INT
  19.     DECLARE cMes CURSOR FOR
  20.  
  21.         SELECT M.Mes
  22.         FROM @Meses M
  23.  
  24.     OPEN cMes
  25.  
  26.     FETCH NEXT FROM cMes
  27.     INTO @Mes
  28.  
  29.     WHILE @@FETCH_STATUS = 0
  30.     BEGIN
  31.         DECLARE @RESULT TABLE
  32.         (
  33.              Id     INT IDENTITY(1,1) PRIMARY KEY
  34.             ,Mes    INT
  35.             ,Nombre VARCHAR(50)
  36.             ,Total  INT
  37.         )
  38.         INSERT INTO @RESULT
  39.                SELECT Q.Mes, Q.Area, Q.Total
  40.                 FROM
  41.                 (
  42.                     SELECT  'Mes' = @Mes
  43.                            ,'Area' = S.Descripcion
  44.                            ,'Total' = ISNULL( COUNT(*), 0)
  45.                     FROM Ausencia a LEFT JOIN Usuario U ON a.Usuario_Id = U.Id
  46.                                     LEFT JOIN Area S ON S.ID = U.Area_Id  
  47.                     WHERE MONTH(CONVERT(CHAR(8), a.Fecha, 112)) = @Mes
  48.                       AND YEAR(CONVERT(CHAR(8), a.Fecha, 112)) = @Anho
  49.                       AND U.Area_Id = @Area_Id
  50.                     GROUP BY S.Descripcion
  51.                    
  52.                     UNION
  53.                    
  54.                     /*Si en algún mes no se registró alguna ausencia le pongo 0*/
  55.                    
  56.                     SELECT  'Mes' = @Mes
  57.                            ,'Area' = S.Descripcion
  58.                            ,'Total' = 0
  59.                     FROM Area S
  60.                     WHERE S.ID = @Area_Id
  61.                 ) Q
  62.        
  63.        
  64.        
  65.         DELETE FROM @RESULT
  66.                WHERE Id IN (SELECT R.Id
  67.                                 FROM @RESULT R INNER JOIN @RESULT R1 ON R.Nombre = R1.Nombre
  68.                                                                     AND R.Id < R1.Id)
  69.         SELECT CASE
  70.                  WHEN Mes = 1
  71.                    THEN 'Enero'
  72.                  WHEN Mes = 2
  73.                    THEN 'Febrero'
  74.                  WHEN Mes = 3
  75.                    THEN 'Marzo'
  76.                  WHEN Mes = 4
  77.                    THEN 'Abril'
  78.                  WHEN Mes = 5
  79.                    THEN 'Mayo'  
  80.                  WHEN Mes = 6
  81.                    THEN 'Junio'
  82.                  WHEN Mes = 7
  83.                    THEN 'Julio'
  84.                  WHEN Mes = 8
  85.                    THEN 'Agosto'
  86.                  WHEN Mes = 9
  87.                    THEN 'Septiembre'
  88.                  WHEN Mes = 10
  89.                    THEN 'Octubre'
  90.                  WHEN Mes = 11
  91.                    THEN 'Nobiembre'
  92.                  WHEN Mes = 12
  93.                    THEN 'Diciembre'      
  94.               END AS 'Mes'     
  95.               ,Nombre
  96.               ,Total
  97.         FROM @RESULT
  98.        
  99.         DELETE @RESULT
  100.        
  101.         FETCH NEXT FROM cMes
  102.         INTO @Mes
  103.     END
  104.  
  105.     CLOSE cMes
  106.     DEALLOCATE cMes

Espero me puedan ayudar.
Gracias.
  #2 (permalink)  
Antiguo 22/03/2017, 13:15
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 3 meses
Puntos: 774
Respuesta: Mejorar el rendimiento del Stored

Para empezar quita el cursor, ahi estas matando el performance, tu proceso puede salir en un solo query, seria algo como esto:


Código SQL:
Ver original
  1. SELECT t1.Nombre, t2.Descripcion, completa.faltas, completa.mes, completa.YEAR FROM usuario AS U
  2. LEFT JOIN (
  3. --Con esto sacamos cuantas veces falto el usuario por mes y año
  4. SELECT COUNT(*) AS faltas, usuario_id, mes, YEAR FROM(
  5. SELECT Usuario_Id, datepart(mm,Fecha) AS mes, datepart(yyyy, fecha) AS YEAR FROM ausencia) AS t1 GROUP BY mes,YEAR, usuario_id) AS completa ON (U.id=completa.usuario_id)
  6. LEFT JOIN area AS t2 ON (t1.area_id=t2.id)
  7. WHERE t2.descripcion='parametro' AND completa.YEAR=parametro

Ojo, este query sacaria los datos de las meses y años donde hay ausencias, si quieres el listado completo por año y los 12 meses haya o no ausencias, ps bueno esa es otra historia :)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 22/03/2017, 13:37
 
Fecha de Ingreso: agosto-2010
Mensajes: 126
Antigüedad: 14 años, 3 meses
Puntos: 9
Respuesta: Mejorar el rendimiento del Stored

Gracias por responder! voy a seguir la tu sugerencia. Saludos

Etiquetas: mejorar, rendimiento, resultado, stored, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:02.