Mejorar el rendimiento de un cursor, cambiarlo a funcion o a una query ...

16/07/2008 - 16:07 por HeliCR | Informe spam
Hola a todos, tengo un cursor pero demanda muchos recursos al generar
un conjunto de registros.

Se tiene una tabla articulos y otra tabla empresas.
Para reconstruir el inventario o el stock se generara una gran
cantidad re registros, ejemplo: Si tengo 50 000 articulos, y 10
empresas entonces generaria 50 000ArticulosX10Empresas X 365 días (Si
quiero reconstruir el inventario para todo un año). La cantidad re
registros generados son millones.

Necesito mejorar el rendimiento de este cursor, convertirlo a
funiones, o quizas a una sola sentencia SQL. Gracias por su ayuda.

El problema lo he resuelto con cursores, pero el rendimiento no es el
esperado, el codigo es el siguiente:


DECLARE @var_empresa varchar(255)
DECLARE c_empresa CURSOR FOR
SELECT ID FROM DATAAREA where upper(ID) = 'IS' Solo tomamos una
empresa (<> DAT tiene que ser)
OPEN c_empresa

FETCH NEXT FROM c_empresa
INTO @var_empresa
WHILE @@FETCH_STATUS = 0

BEGIN

DECLARE @fecha1 datetime, @fecha2 datetime,@valor_fecha datetime
SET @fecha1='04/05/2008'
SET @fecha2='05/05/2008'
DECLARE c_interfechas CURSOR FOR
SELECT BISaludes.dwh.DIM_FECHA.Fecha from BISaludes.dwh.DIM_FECHA
where BISaludes.dwh.DIM_FECHA.Fecha>=@fecha1 and
BISaludes.dwh.DIM_FECHA.Fecha<=@fecha2
open c_interfechas

FETCH NEXT FROM c_interfechas
INTO @valor_fecha

WHILE @@FETCH_STATUS = 0
BEGIN
insert into TT_ValoresInventario

SELECT distinct null AS IDValorInventario, itemid,@var_empresa as
IDEmpresa,null as stock,null as importe,GETDATE() AS
Fecha_Carga,@valor_fecha as Fecha_Inventario,
null as stock_inventsum,null as inventsum,null as
stock_inventtrans,null as importe_inventtrans
from inventtable
where inventtable.itemid in (select distinct itemid from inventtrans
union select distinct itemid from inventsum)

FETCH NEXT FROM c_interfechas
INTO @valor_fecha

END
CLOSE c_interfechas
DEALLOCATE c_interfechas

FETCH NEXT FROM c_empresa
INTO @var_empresa

END
CLOSE c_empresa
DEALLOCATE c_empresa

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
16/07/2008 - 16:45 | Informe spam
Trata:

A proposito, me llama la atencion que el [id] de la empresa este definido
como varchar(255).

DECLARE @var_empresa varchar(255)
DECLARE @fecha1 datetime, @fecha2 datetime
declare @Fecha_Carga datetime

set @Fecha_Carga = getdate()
set @var_empresa = 'IS'
SET @fecha1='20080504'
SET @fecha2='20080505'

SELECT
null AS IDValorInventario,
itemid,
@var_empresa as IDEmpresa,
null as stock,
null as importe,
@Fecha_Carga,
f.Fecha as Fecha_Inventario,
null as stock_inventsum,
null as inventsum,
null as stock_inventtrans,
null as importe_inventtrans
from
(
select distinct i.itemid
from inventtable as i
) as b
cross join
(
SELECT
a.Fecha
from
BISaludes.dwh.DIM_FECHA as a
where
a.Fecha>=@fecha1
and a.Fecha<=@fecha2
) as f
where
exists (
select *
from inventtrans as c
where c.itemid = b.itemid
)
or exists (
select *
from inventsum as d
where d.itemid = b.itemid
)
GO


AMB



"HeliCR" wrote:

Hola a todos, tengo un cursor pero demanda muchos recursos al generar
un conjunto de registros.

Se tiene una tabla articulos y otra tabla empresas.
Para reconstruir el inventario o el stock se generara una gran
cantidad re registros, ejemplo: Si tengo 50 000 articulos, y 10
empresas entonces generaria 50 000ArticulosX10Empresas X 365 días (Si
quiero reconstruir el inventario para todo un año). La cantidad re
registros generados son millones.

Necesito mejorar el rendimiento de este cursor, convertirlo a
funiones, o quizas a una sola sentencia SQL. Gracias por su ayuda.

El problema lo he resuelto con cursores, pero el rendimiento no es el
esperado, el codigo es el siguiente:


DECLARE @var_empresa varchar(255)
DECLARE c_empresa CURSOR FOR
SELECT ID FROM DATAAREA where upper(ID) = 'IS' Solo tomamos una
empresa (<> DAT tiene que ser)
OPEN c_empresa

FETCH NEXT FROM c_empresa
INTO @var_empresa
WHILE @@FETCH_STATUS = 0

BEGIN

DECLARE @fecha1 datetime, @fecha2 datetime,@valor_fecha datetime
SET @fecha1='04/05/2008'
SET @fecha2='05/05/2008'
DECLARE c_interfechas CURSOR FOR
SELECT BISaludes.dwh.DIM_FECHA.Fecha from BISaludes.dwh.DIM_FECHA
where BISaludes.dwh.DIM_FECHA.Fecha>=@fecha1 and
BISaludes.dwh.DIM_FECHA.Fecha<=@fecha2
open c_interfechas

FETCH NEXT FROM c_interfechas
INTO @valor_fecha

WHILE @@FETCH_STATUS = 0
BEGIN
insert into TT_ValoresInventario

SELECT distinct null AS IDValorInventario, itemid,@var_empresa as
IDEmpresa,null as stock,null as importe,GETDATE() AS
Fecha_Carga,@valor_fecha as Fecha_Inventario,
null as stock_inventsum,null as inventsum,null as
stock_inventtrans,null as importe_inventtrans
from inventtable
where inventtable.itemid in (select distinct itemid from inventtrans
union select distinct itemid from inventsum)

FETCH NEXT FROM c_interfechas
INTO @valor_fecha

END
CLOSE c_interfechas
DEALLOCATE c_interfechas

FETCH NEXT FROM c_empresa
INTO @var_empresa

END
CLOSE c_empresa
DEALLOCATE c_empresa

Respuesta Responder a este mensaje
#2 HeliCR
16/07/2008 - 17:04 | Informe spam
Gracias Alejando, probare con el codigo que mandaste
Lo del ID de la empresa se me fue.

Saludos y gracias otra vez


On 16 jul, 16:45, Alejandro Mesa
wrote:
Trata:

A proposito, me llama la atencion que el [id] de la empresa este definido
como varchar(255).

DECLARE @var_empresa varchar(255)
DECLARE @fecha1 datetime, @fecha2 datetime
declare @Fecha_Carga datetime

set @Fecha_Carga = getdate()
set @var_empresa = 'IS'
SET @fecha1='20080504'
SET @fecha2='20080505'

SELECT
        null AS IDValorInventario,
        itemid,
        @var_empresa as IDEmpresa,
        null as stock,
        null as importe,
        @Fecha_Carga,
        f.Fecha as Fecha_Inventario,
        null as stock_inventsum,
        null as inventsum,
        null as stock_inventtrans,
        null as importe_inventtrans
from
        (
        select distinct i.itemid
        from inventtable as i
        ) as b
        cross join
        (
        SELECT
                a.Fecha
        from
                BISaludes.dwh.DIM_FECHA as a
        where
                a.Fecha>=@fecha1
                and a.Fecha<=@fecha2
        ) as f
where
        exists (
        select *
        from inventtrans as c
        where c.itemid = b.itemid
        )
        or exists (
        select *
        from inventsum as d
        where d.itemid = b.itemid
        )
GO

AMB

"HeliCR" wrote:
> Hola a todos, tengo un cursor pero demanda muchos recursos al generar
> un conjunto de registros.

> Se tiene una tabla articulos y otra tabla empresas.
> Para reconstruir el inventario o el stock se generara una gran
> cantidad re registros, ejemplo: Si tengo 50 000 articulos, y 10
> empresas entonces generaria 50 000ArticulosX10Empresas X 365 días (Si
> quiero reconstruir el inventario para todo un año).  La cantidad re
> registros generados son millones.

> Necesito mejorar el rendimiento de este cursor, convertirlo a
> funiones, o quizas a una sola sentencia SQL. Gracias por su ayuda.

> El problema lo he resuelto con cursores, pero el rendimiento no es el
> esperado, el codigo es el siguiente:

> DECLARE @var_empresa varchar(255)
> DECLARE c_empresa CURSOR FOR
> SELECT ID FROM DATAAREA where upper(ID) = 'IS' Solo tomamos una
> empresa (<> DAT tiene que ser)
> OPEN c_empresa

> FETCH NEXT FROM c_empresa
> INTO @var_empresa
> WHILE @@FETCH_STATUS = 0

> BEGIN

> DECLARE @fecha1 datetime, @fecha2 datetime,@valor_fecha datetime
> SET @fecha1='04/05/2008'
> SET @fecha2='05/05/2008'
> DECLARE c_interfechas CURSOR FOR
> SELECT BISaludes.dwh.DIM_FECHA.Fecha from  BISaludes.dwh.DIM_FECHA
> where BISaludes.dwh.DIM_FECHA.Fecha>=@fecha1 and
> BISaludes.dwh.DIM_FECHA.Fecha<=@fecha2
> open c_interfechas

> FETCH NEXT FROM c_interfechas
> INTO @valor_fecha

> WHILE @@FETCH_STATUS = 0
> BEGIN
> insert into TT_ValoresInventario

> SELECT distinct  null AS IDValorInventario, itemid,@var_empresa as
> IDEmpresa,null as stock,null as importe,GETDATE() AS
> Fecha_Carga,@valor_fecha as Fecha_Inventario,
> null as stock_inventsum,null as inventsum,null as
> stock_inventtrans,null as importe_inventtrans
>  from inventtable
> where inventtable.itemid in (select distinct itemid from inventtrans
> union select distinct itemid from inventsum)

> FETCH NEXT FROM c_interfechas
> INTO @valor_fecha

> END
> CLOSE c_interfechas
> DEALLOCATE c_interfechas

> FETCH NEXT FROM c_empresa
> INTO @var_empresa

> END
> CLOSE  c_empresa
> DEALLOCATE  c_empresa
Respuesta Responder a este mensaje
#3 HeliCR
16/07/2008 - 17:08 | Informe spam
Perfecta la solución.

Saludos Alejandro


On 16 jul, 16:45, Alejandro Mesa
wrote:
Trata:

A proposito, me llama la atencion que el [id] de la empresa este definido
como varchar(255).

DECLARE @var_empresa varchar(255)
DECLARE @fecha1 datetime, @fecha2 datetime
declare @Fecha_Carga datetime

set @Fecha_Carga = getdate()
set @var_empresa = 'IS'
SET @fecha1='20080504'
SET @fecha2='20080505'

SELECT
        null AS IDValorInventario,
        itemid,
        @var_empresa as IDEmpresa,
        null as stock,
        null as importe,
        @Fecha_Carga,
        f.Fecha as Fecha_Inventario,
        null as stock_inventsum,
        null as inventsum,
        null as stock_inventtrans,
        null as importe_inventtrans
from
        (
        select distinct i.itemid
        from inventtable as i
        ) as b
        cross join
        (
        SELECT
                a.Fecha
        from
                BISaludes.dwh.DIM_FECHA as a
        where
                a.Fecha>=@fecha1
                and a.Fecha<=@fecha2
        ) as f
where
        exists (
        select *
        from inventtrans as c
        where c.itemid = b.itemid
        )
        or exists (
        select *
        from inventsum as d
        where d.itemid = b.itemid
        )
GO

AMB

"HeliCR" wrote:
> Hola a todos, tengo un cursor pero demanda muchos recursos al generar
> un conjunto de registros.

> Se tiene una tabla articulos y otra tabla empresas.
> Para reconstruir el inventario o el stock se generara una gran
> cantidad re registros, ejemplo: Si tengo 50 000 articulos, y 10
> empresas entonces generaria 50 000ArticulosX10Empresas X 365 días (Si
> quiero reconstruir el inventario para todo un año).  La cantidad re
> registros generados son millones.

> Necesito mejorar el rendimiento de este cursor, convertirlo a
> funiones, o quizas a una sola sentencia SQL. Gracias por su ayuda.

> El problema lo he resuelto con cursores, pero el rendimiento no es el
> esperado, el codigo es el siguiente:

> DECLARE @var_empresa varchar(255)
> DECLARE c_empresa CURSOR FOR
> SELECT ID FROM DATAAREA where upper(ID) = 'IS' Solo tomamos una
> empresa (<> DAT tiene que ser)
> OPEN c_empresa

> FETCH NEXT FROM c_empresa
> INTO @var_empresa
> WHILE @@FETCH_STATUS = 0

> BEGIN

> DECLARE @fecha1 datetime, @fecha2 datetime,@valor_fecha datetime
> SET @fecha1='04/05/2008'
> SET @fecha2='05/05/2008'
> DECLARE c_interfechas CURSOR FOR
> SELECT BISaludes.dwh.DIM_FECHA.Fecha from  BISaludes.dwh.DIM_FECHA
> where BISaludes.dwh.DIM_FECHA.Fecha>=@fecha1 and
> BISaludes.dwh.DIM_FECHA.Fecha<=@fecha2
> open c_interfechas

> FETCH NEXT FROM c_interfechas
> INTO @valor_fecha

> WHILE @@FETCH_STATUS = 0
> BEGIN
> insert into TT_ValoresInventario

> SELECT distinct  null AS IDValorInventario, itemid,@var_empresa as
> IDEmpresa,null as stock,null as importe,GETDATE() AS
> Fecha_Carga,@valor_fecha as Fecha_Inventario,
> null as stock_inventsum,null as inventsum,null as
> stock_inventtrans,null as importe_inventtrans
>  from inventtable
> where inventtable.itemid in (select distinct itemid from inventtrans
> union select distinct itemid from inventsum)

> FETCH NEXT FROM c_interfechas
> INTO @valor_fecha

> END
> CLOSE c_interfechas
> DEALLOCATE c_interfechas

> FETCH NEXT FROM c_empresa
> INTO @var_empresa

> END
> CLOSE  c_empresa
> DEALLOCATE  c_empresa
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida