Siguiendo los consejos del grupo he realizado un proceso almacenado para
actualizar una tabla de más de 33 millones de registros, pero me funciona
muy lento, para actualizar 50.000 registros tarda dos horas y esto al
cliente le parece excesivo, así que os mando el código para ver si alguien
me ayuda a optimizarlo.
Este código es mi primera experiencia con cursores y procesos almacenados,
así que estoy convencido de que no debe ser la mejor forma de usarlos, así
que cualquier consejo será muy bien recibido.
Aquí va el código:
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'get_ID_TP_TDA' AND type = 'P')
DROP PROCEDURE get_ID_TP_TDA
GO
CREATE PROCEDURE get_ID_TP_TDA
@TpTda varchar(1) OUTPUT
AS
DECLARE @Empr decimal
DECLARE @Tda decimal
DECLARE @Del decimal
SELECT TOP 1
@Empr = ID_EMPR,
@Tda = ID_TDA,
@Del = ID_DEL
FROM
Ventas
WHERE
ID_TP_TDA IS NULL
SELECT
@TpTda = ID_TP_TDA
FROM
Tiendas
WHERE
ID_EMPR = @Empr AND
ID_TDA = @Tda AND
ID_DEL = @Del
RETURN
GO
DECLARE MiCursor CURSOR
FOR
SELECT
ID_TP_TDA
FROM
Ventas
WHERE
ID_TP_TDA IS NULL
FOR UPDATE OF ID_TP_TDA
OPEN MiCursor
DECLARE @NUMERO_DE_REGISTROS_ACTUALIZADOS int
SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = 0
DECLARE @HORA_INICIAL datetime
SET @HORA_INICIAL = GETDATE()
WHILE (@@FETCH_STATUS = 0 AND @NUMERO_DE_REGISTROS_ACTUALIZADOS < 50000) /*
< Numero de registros máximo a actualizar */
BEGIN
DECLARE @TipoTienda varchar(1)
DECLARE @TipoTiendaNULL varchar(1)
EXECUTE get_ID_TP_TDA
@TpTda = @TipoTienda OUTPUT
FETCH NEXT FROM MiCursor INTO @TipoTiendaNULL /* Evita que el resultado
se muestre en pantalla */
UPDATE
Ventas
SET
Ventas.ID_TP_TDA = @TipoTienda
FROM
Ventas
WHERE CURRENT OF MiCursor
SET @NUMERO_DE_REGISTROS_ACTUALIZADOS = @NUMERO_DE_REGISTROS_ACTUALIZADOS +
1
END
DECLARE @HORA_FINAL datetime
SET @HORA_FINAL = GETDATE()
SELECT @NUMERO_DE_REGISTROS_ACTUALIZADOS AS 'Número de registros',
@HORA_INICIAL as 'Hora de comienzo', @HORA_FINAL as 'Hora de finalización'
CLOSE MiCursor
DEALLOCATE MiCursor
Muchas gracias a todos
Javi
Leer las respuestas