Ver Mensaje Individual
  #1 (permalink)  
Antiguo 09/05/2006, 15:55
Avatar de Myakire
Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 23 años
Puntos: 146
Optimizar un SP que traspone una tabla

Tengo un par de vistas que obtienen ciertos registros de la BD's, pero los obtengo por filas y los requiero por columnas, así que implementé un SP que traspone a mis necesidades la información, pero el problema es que se tarda mucho. Para una consulta que regresa 100 registros, se tarda casi 2 minutos para ejecutar el SP.

El detalle es que hago varias concatenaciones por que necesito la información con ciertas características:
1) Debe haber 4 columnas: M, P, T y O adicionales a la de la llave (NoParte). Las 3 columnas primeras son 'unicas y la 4a es el acumulado del resto de los valores del campo "Almacen"
2) La vista puede regresarme 1 o más registros pertenecientes a x número de almacenes, a veces 1 o 2 almacenes, a veces más y en cualquier orden.

Para forzar a que siempre se formen las 4 columnas en orden, hago acumulados y concatenaciones.

Si alguien pudiera darme una idea de como optimizar el SP, se lo agradecería mucho, el SP es el siguiente:


Código:
CREATE PROCEDURE sResumen_Assort_Inventario
AS
BEGIN

DECLARE @NoParte varchar(10)
DECLARE @NomAlmacen VARCHAR(50)
DECLARE @Valor float
DECLARE @Suma float

DECLARE @AlmacenM float
DECLARE @AlmacenP float
DECLARE @AlmacenT float


DECLARE @Count INT
DECLARE @GrantCount INT
DECLARE @Select VARCHAR(8000)
DECLARE @GrantSelect VARCHAR(8000)

DECLARE @CadAlmacenes VARCHAR(10)
DECLARE @Salida VARCHAR(8000)
DECLARE @IDAlmacen CHAR(1)

SET @GrantCount = 0
SET @GrantSelect = ''

DECLARE NumerosDeParte CURSOR SCROLL FOR
(SELECT NoParte
 FROM vw_Assort_Esp
 GROUP BY NoParte)

OPEN NumerosDeParte

FETCH FIRST FROM NumerosDeParte INTO @NoParte
WHILE @@FETCH_STATUS = 0
BEGIN
      DECLARE CurExistencias CURSOR SCROLL FOR 
      (SELECT Almacen, TonTotales, NoParte
      FROM vw_Assort_Inv
      WHERE NoParte = @NoParte)

      SET @Select = ''
      SET @Count = 0
      SET @CadAlmacenes = ''
      SET @Suma = 0
      SET @AlmacenM = 0
      SET @AlmacenP = 0
      SET @AlmacenT = 0
      
      OPEN CurExistencias
      FETCH FIRST FROM CurExistencias INTO @NomAlmacen, @Valor, @NoParte
      WHILE @@FETCH_STATUS = 0
      BEGIN
            SET @Count = @Count + 1
            SET @NomAlmacen = RTRIM(LTRIM(@NomAlmacen))
            IF @Count = 1
                SET @Select = @Select + ' SELECT NoParte=''' + RTRIM(LTRIM(@NoParte))+''''

            IF @NomAlmacen='M' OR @NomAlmacen='P' OR @NomAlmacen='T' 
            BEGIN
                 IF @NomAlmacen = 'M'
                       SET @AlmacenM = @Valor
                 IF @NomAlmacen = 'P'
                       SET @AlmacenP = @Valor
                 IF @NomAlmacen = 'T'
                       SET @AlmacenT = @Valor
            END
            ELSE
                 SET  @Suma = @Suma + @Valor

            SET @CadAlmacenes = @CadAlmacenes + @NomAlmacen

            FETCH NEXT FROM CurExistencias INTO @NomAlmacen, @Valor, @NoParte
      END

      CLOSE CurExistencias
      DEALLOCATE CurExistencias


      SET @Salida = ''
      DECLARE CurAlmacenes CURSOR SCROLL FOR  (SELECT Almacen FROM Almacenes WHERE Tipo='E')
      OPEN CurAlmacenes
      FETCH FIRST FROM CurAlmacenes INTO @IDAlmacen
      WHILE @@FETCH_STATUS = 0
      BEGIN
           IF CHARINDEX(@IDAlmacen, @CadAlmacenes)=0
           BEGIN
               IF RTRIM(LTRIM(@IDAlmacen))='M' OR RTRIM(LTRIM(@IDAlmacen))='P' OR RTRIM(LTRIM(@IDAlmacen))='T' 
               BEGIN
                   SET @Salida = @Salida +  ', ' + @IDAlmacen + '= ''0'''
               END
           END
           ELSE
               BEGIN
                    IF @IDAlmacen = 'M'
                       SET @Salida = @Salida +  ',M= '''+CONVERT(VARCHAR,@AlmacenM)+'''' 
                    IF @IDAlmacen = 'P'
                       SET @Salida = @Salida +  ',P= '''+CONVERT(VARCHAR,@AlmacenP)+'''' 
                    IF @IDAlmacen = 'T'
                       SET @Salida = @Salida +  ',T= '''+CONVERT(VARCHAR,@AlmacenT)+'''' 
               END
 
           FETCH NEXT FROM CurAlmacenes INTO @IDAlmacen
      END
      CLOSE CurAlmacenes
      DEALLOCATE CurAlmacenes

      IF @Suma > 0
          SET @Salida = @Salida +  ', NG= '''+CONVERT(VARCHAR,@Suma)+''''
      ELSE
          SET @Salida = @Salida +  ', NG= ''0'''

      IF @Count=0
           SET @Select = @Select + ' SELECT NoParte=''' + RTRIM(LTRIM(CONVERT(VARCHAR,@NoParte)))+'''' + @Salida
      ELSE 
           SET @Select = @Select + @Salida

      SET @Select = @Select + CHAR(13)

      SET @GrantCount = @GrantCount + 1
      IF @GrantCount = 1
            SET @GrantSelect = @Select
      ELSE
            SET @GrantSelect = @GrantSelect + CHAR(13) + ' UNION ' + CHAR(13)+  @Select

      FETCH NEXT FROM NumerosDeParte INTO @NoParte
END
PRINT(@GrantSelect)
EXEC(@GrantSelect)
CLOSE NumerosDeParte
DEALLOCATE NumerosDeParte
END
GO