Optimizar stored procedure
- From: mbgbrown1@xxxxxxxxxxx
- Date: Thu, 29 May 2008 17:35:01 -0700 (PDT)
Buenas Tardes:
Alguien me podria decir como puedo hacer este stored procedure mas
rapido?? estoy usando SYBASE y tarda 00:13:47 en ejecutarse, necesito
que tarde menos de 6 minutos en ejecutarse. Ojala alguien pueda
ayudarme.
Gracias.
CREATE PROCEDURE PR_POP_UB_USRDETBYSIDNID
@dINIT_DATE datetime=NULL,
@dEND_DATE datetime=NULL
AS
DECLARE @dINIT_DATE_AUX DATETIME,
@dEND_DATE_AUX DATETIME,
@dINIT_DATE_COPY DATETIME,
@dEND_DATE_COPY DATETIME,
@dINIT_DATE_AUX_COPY DATETIME,
@dEND_DATE_AUX_COPY DATETIME,
@iCONTADOR INT,
@CUR_SID VARCHAR(15),
@CUR_NID VARCHAR(15),
@iTOTAL INT,
@iTOTAL_BAZ INT,
@iTOTAL_EKT INT,
@iTOTAL_IUS INT,
@USRS_BAZ INT,
@USRS_EKT INT,
@USRS_IUS INT,
@USRS_TOT INT,
@iTOTAL_BAD INT,
@INIT_PROC DATETIME,
@END_PROC DATETIME,
@ID_BEGIN INT,
@ID_END INT,
@CTL_ID_BEGIN INT,
@CTL_DATE_ID_BEGIN DATETIME,
@CTL_ID_END INT,
@CTL_DATE_ID_END DATETIME
SET NOCOUNT ON
SELECT @INIT_PROC = (SELECT GETDATE())
-- VALIDO LA INTEGRIDAD DE LOS PARAMETROS
IF(@dINIT_DATE IS NULL AND @dEND_DATE IS NOT NULL) OR (@dINIT_DATE
IS NOT NULL AND @dEND_DATE IS NULL)
BEGIN
SELECT 'ERROR'=-1,'ERROR_DESC'= 'SOLO EXISTEN 2 POSIBILIDADES
DE EJECUTAR ESTE SP. 1) ENVIE FECHA INICIAL Y FECHA FINAL 2) NO ENVIE
NADA EL SP CONSULTARA A LA TABLA DE CONTROL'
RETURN -1
END
CREATE TABLE #TMP_UB_USRDETBYSIDNID2 (
ID_CSV int NOT NULL,
PMM_DATETIME datetime NOT NULL,
SID varchar(15) NULL,
NID varchar(15) NULL,
MINid varchar(15) NOT NULL
)
CREATE INDEX IX_#TMP_UB_USRDETBYSIDNID2
ON #TMP_UB_USRDETBYSIDNID2(PMM_DATETIME, SID, NID)
IF(@dINIT_DATE IS NULL)
BEGIN
-- CHECO EL DATE_ID_END DE LA TABLA DE CONTROL PARA SABER
HASTA QUE FECHA ME QUEDE
SELECT @dINIT_DATE = (SELECT DATE_ID_END FROM CTL_TABLES WHERE
TABLE_NAME='UB_USRDETBYSIDNID')
IF (@dINIT_DATE IS NULL)
BEGIN
-- SIGNIFICA QUE POR ALGUNA RAZON LA TABLA DE CONTROL NO
SABE EN QUE FECHA NOS QUEDAMOS
-- POR LO TANTO, VOY A LA TABLA DESTINO Y REVISO LA
ULTIMA FECHA CAPTURADA
SELECT @dINIT_DATE = (SELECT MAX(PMM_DATETIME) FROM
UB_USRDETBYSIDNID)
IF(@dINIT_DATE IS NULL)
BEGIN
-- SIGNIFICA QUE NO HAY INFORMACION CONFIABLE EN LA
TABLA DESTINO
SELECT 'ERROR'=-1,'ERROR_DESC'= 'AL CONSULTAR LA TABLA
UB_USRDETBYSIDNID2 NO FUE POSIBLE ESTABLECER LA FECHA INICIAL DE
BUSQUEDA PARA ESTA OPERACION'
RETURN -1
END
END
-- DE AQUI RESTO 2 HORAS PARA ASEGURAR OBTENER LA INFORMACION
MAS RECIENTE
SELECT @dINIT_DATE = (SELECT
DATEADD(hour,-2,@dINIT_DATE))
SELECT @dINIT_DATE=CONVERT(VARCHAR(2), DATEPART(mm,
@dINIT_DATE)) + "/" +
CONVERT(VARCHAR(2), DATEPART(dd, @dINIT_DATE)) + "/" +
CONVERT(VARCHAR(4), DATEPART(yy, @dINIT_DATE)) + " " +
CONVERT(VARCHAR(2), DATEPART(hh, @dINIT_DATE)) + ":
00:00"
SELECT @dEND_DATE = (SELECT GETDATE())
END
ELSE
BEGIN
-- SIGNIFICA QUE EL USUARIO HA ELEGIDO EL PERIODO DE TIEMPO
EN EL CUAL BUSCARA INFORMACION EN LA TABLA CSV.
-- VALIDO QUE LA FECHA INICIAL SEA MENOR O IGUAL A LA FECHA
FINAL.
IF(@dINIT_DATE > @dEND_DATE)
BEGIN
SELECT 'ERROR'=-1,'ERROR_DESC'= 'LA FECHA INICIAL ES MAYOR
A LA FINAL, FECHAL INICIAL: ' +
CONVERT(VARCHAR(19),CONVERT(VARCHAR(10), @dINIT_DATE,102)
+ ' ' + CONVERT(VARCHAR(8), @dINIT_DATE,108)) + ' FECHA FINAL: ' +
CONVERT(VARCHAR(19),CONVERT(VARCHAR(10), @dEND_DATE,102) +
' ' + CONVERT(VARCHAR(8), @dEND_DATE,108))
RETURN -1
END
END
INSERT INTO #TMP_UB_USRDETBYSIDNID2
SELECT ID_CSV,
PMM_DATETIME,
SID,
NID,
MINid
FROM CSV
WHERE PMM_DATETIME BETWEEN @dINIT_DATE AND @dEND_DATE
ORDER BY PMM_DATETIME
IF @@ROWCOUNT = 0
BEGIN
SELECT 'ERROR'=-1,'ERROR_DESC'= 'NO HAY INFORMACION DISPONIBLE EN
EL PERIODO: ' +
CONVERT(VARCHAR(19),CONVERT(VARCHAR(10), @dINIT_DATE,102)
+ ' ' + CONVERT(VARCHAR(8), @dINIT_DATE,108)) + ' AL ' +
CONVERT(VARCHAR(19),CONVERT(VARCHAR(10), @dEND_DATE,102) +
' ' + CONVERT(VARCHAR(8), @dEND_DATE,108))
RETURN -1
END
-- DEBO HACER LA BUSQUEDA DEL @ID_BEGIN MAS PEQUEÑO DENTRO DEL
INTERVALO
SELECT @ID_BEGIN = (SELECT MIN(ID_CSV) FROM
#TMP_UB_USRDETBYSIDNID2)
-- YA TENGO EL @ID_BEGIN, DEBO ENCONTRAR EL @ID_END
SELECT @ID_END = (SELECT MAX(ID_CSV) FROM #TMP_UB_USRDETBYSIDNID2)
-- AHORA ENCUENTRO LA FECHA INICIAL Y LA FINAL
SELECT @dINIT_DATE = (SELECT MIN(PMM_DATETIME) FROM
#TMP_UB_USRDETBYSIDNID2)
SELECT @dEND_DATE = (SELECT MAX(PMM_DATETIME) FROM
#TMP_UB_USRDETBYSIDNID2)
-- RESPALDO LAS VARIABLES PARA QUE POSTERIORMENTE ACTUALIZE LA
TABLA DE CONTROL
SELECT @CTL_ID_BEGIN = @ID_BEGIN
SELECT @CTL_DATE_ID_BEGIN = @dINIT_DATE
SELECT @CTL_ID_END = @ID_END
SELECT @CTL_DATE_ID_END = @dEND_DATE
-- SE DEBE AJUSTAR EL @dINIT_DATE A LA HORA QUE PERTENEZCA.
SELECT @dINIT_DATE_AUX = (SELECT CONVERT(DATETIME,
(CONVERT(VARCHAR(10),@dINIT_DATE,102) + ' 00:00:00')))
SELECT @dEND_DATE_AUX = (SELECT CONVERT(DATETIME,
(CONVERT(VARCHAR(10),@dINIT_DATE,102) + ' 00:04:59')))
WHILE (@dINIT_DATE_AUX <= @dEND_DATE_AUX)
BEGIN
IF ((@dINIT_DATE >= @dINIT_DATE_AUX) AND (@dINIT_DATE <=
@dEND_DATE_AUX))
BEGIN
SELECT @dINIT_DATE = @dINIT_DATE_AUX
SELECT @dINIT_DATE_AUX = NULL
BREAK
END
ELSE
BEGIN
SELECT @dINIT_DATE_AUX = (SELECT DATEADD(ss,
300,@dINIT_DATE_AUX))
SELECT @dEND_DATE_AUX = (SELECT DATEADD(ss,
299,@dINIT_DATE_AUX))
END
END
-- AJUSTO EL PRIMER INTERVALO DE BUSQUEDA
SELECT @dEND_DATE_AUX = (SELECT DATEADD(ss,299,@dINIT_DATE))
SELECT @iCONTADOR = 0
CREATE TABLE #TMP2_UB_USRDETBYSIDNID2 (
ID_CSV int NOT NULL,
PMM_DATETIME datetime NULL,
SID varchar(15) NOT NULL,
NID varchar(15) NOT NULL,
MINid varchar(15) NOT NULL
)
CREATE INDEX IX_#TMP2_UB_USRDETBYSIDNID2
ON #TMP2_UB_USRDETBYSIDNID2(PMM_DATETIME, SID, NID)
-- INICIO CURSOR PARA OBTENER LAS ESTADISTICAS POR CADA UNO DE LOS
SID/NID ACTIVOS EN LA TABLA SID_NID_CENTRALES
DECLARE
CURSIDS
CURSOR FOR
SELECT
DISTINCT(SID) AS 'SIDS',
NID AS 'NID'
FROM SID_NID_CENTRALES
WHERE BSTATUS = 1
ORDER BY SID
OPEN CURSIDS
FETCH
CURSIDS
INTO
@CUR_SID,
@CUR_NID
WHILE (@@sqlstatus = 0)
BEGIN
-- RESPALDO LAS VARIABLES
SELECT
@dINIT_DATE_COPY = @dINIT_DATE,
@dEND_DATE_COPY = @dEND_DATE,
@dEND_DATE_AUX_COPY = @dEND_DATE_AUX
-- INSERTO LOS REGISTROS QUE SEAN IGUALES AL SID Y NID
CORRESPONDIENTES EN LA 2DA TABLA TEMPORAL
INSERT INTO #TMP2_UB_USRDETBYSIDNID2
SELECT
ID_CSV,
PMM_DATETIME,
@CUR_SID,
@CUR_NID,
MINid
FROM #TMP_UB_USRDETBYSIDNID2
WHERE
SID = @CUR_SID AND
NID = @CUR_NID
-- SE OBTIENE TODA LA INFORMACION DE LA TABLA DE ORIGEN DESDE
EL INTERVALO INICIAL AJUSTADO HASTA EL INTERVALO FINAL EXACTO.
WHILE (@dINIT_DATE <= @dEND_DATE)
BEGIN
SELECT
@iTOTAL = 0,
@iTOTAL_BAZ = 0,
@iTOTAL_EKT = 0,
@iTOTAL_IUS = 0,
@USRS_BAZ = 0,
@USRS_EKT = 0,
@USRS_IUS = 0,
@USRS_TOT = 0
SELECT @USRS_BAZ = COUNT(DISTINCT(A.MINid))
FROM #TMP2_UB_USRDETBYSIDNID2 A, usr_mines B
WHERE A.PMM_DATETIME BETWEEN @dINIT_DATE AND
@dEND_DATE_AUX
AND A.SID = @CUR_SID AND A.NID = @CUR_NID AND B.corpo_id
= 'BAZ'
AND A.MINid = B.MIN_id
SELECT @USRS_EKT = COUNT(DISTINCT(A.MINid))
FROM #TMP2_UB_USRDETBYSIDNID2 A, usr_mines B
WHERE A.PMM_DATETIME BETWEEN @dINIT_DATE AND
@dEND_DATE_AUX
AND A.SID = @CUR_SID AND A.NID = @CUR_NID AND B.corpo_id
= 'EKT'
AND A.MINid = B.MIN_id
DELETE #TMP2_UB_USRDETBYSIDNID2
FROM #TMP2_UB_USRDETBYSIDNID2 A, usr_mines B
WHERE A.PMM_DATETIME BETWEEN @dINIT_DATE AND
@dEND_DATE_AUX
AND A.SID = @CUR_SID AND A.NID = @CUR_NID AND (B.corpo_id
= 'EKT'
OR B.corpo_id = 'BAZ')
AND A.MINid = B.MIN_id
SELECT @USRS_IUS = COUNT(DISTINCT(MINid))
FROM #TMP2_UB_USRDETBYSIDNID2
WHERE
PMM_DATETIME BETWEEN @dINIT_DATE AND @dEND_DATE_AUX AND
SID = @CUR_SID AND
NID = @CUR_NID
SELECT @USRS_TOT= ISNULL(@USRS_BAZ,0)+ISNULL(@USRS_EKT,
0)+ISNULL(@USRS_IUS,0)
-- ACTUALIZA EL REGISTRO EXISTENTE CON LAS NUEVAS
CANTIDADES OBTENIDAS.
UPDATE UB_USRDETBYSIDNID
SET SID = @CUR_SID,
NID = @CUR_NID,
USRS_BAZ = ISNULL(@USRS_BAZ,0),
USRS_EKT = ISNULL(@USRS_EKT,0),
USRS_IUS = ISNULL(@USRS_IUS,0),
USRS_TOT = ISNULL(@USRS_TOT,0)
WHERE PMM_DATETIME = @dINIT_DATE AND
SID = @CUR_SID AND NID = @CUR_NID
IF @@ROWCOUNT = 0
BEGIN
-- SIGNIFICA QUE NO HAY INFORMACION EN LA TABLA
DESTINO PARA EL INTERVALO DE TIEMPO EN CUESTION, ES NUEVO
INSERT INTO UB_USRDETBYSIDNID
VALUES(@dINIT_DATE,@CUR_SID,@CUR_NID,ISNULL(@USRS_BAZ,
0),ISNULL(@USRS_EKT,0),ISNULL(@USRS_IUS,0),ISNULL(@USRS_TOT,0))
END
DELETE #TMP2_UB_USRDETBYSIDNID2
WHERE
PMM_DATETIME BETWEEN @dINIT_DATE AND @dEND_DATE_AUX
AND
SID = @CUR_SID AND
NID = @CUR_NID
-- INCREMENTO LAS VARIABLES.
SELECT @iCONTADOR = @iCONTADOR + 1
SELECT @dINIT_DATE = (SELECT DATEADD(ss,
300,@dINIT_DATE))
SELECT @dEND_DATE_AUX = (SELECT DATEADD(ss,
299,@dINIT_DATE))
END
-- RECUPERO LAS VARIABLES.
SELECT
@dINIT_DATE = @dINIT_DATE_COPY,
@dEND_DATE = @dEND_DATE_COPY,
@dEND_DATE_AUX = @dEND_DATE_AUX_COPY
DELETE #TMP_UB_USRDETBYSIDNID2
WHERE
SID = @CUR_SID AND
NID = @CUR_NID
FETCH
CURSIDS
INTO
@CUR_SID,
@CUR_NID
-- LIMPIO LA TABLA LA 2DA TABLA TEMPORAL
TRUNCATE TABLE #TMP2_UB_USRDETBYSIDNID2
END
CLOSE CURSIDS
DEALLOCATE cursor CURSIDS
SELECT @END_PROC = (SELECT GETDATE())
SELECT 'ERROR'=0,'ERROR_DESC'= 'MOVIMIENTO EXITOSO SE REALIZARON '
+ CONVERT(VARCHAR(12),@iCONTADOR) + ' INSERCIONES A LA TABLA
UB_USRDETBYSIDNID2 ' +
' EL PERIODO DE EJECUCION FUE DE: ' +
CONVERT(VARCHAR(19),CONVERT(VARCHAR(10),@INIT_PROC,102) + ' ' +
CONVERT(VARCHAR(8),@INIT_PROC,108)) +
' HASTA ' + CONVERT(VARCHAR(19),CONVERT(VARCHAR(10),@END_PROC,102)
+ ' ' + CONVERT(VARCHAR(8),@END_PROC,108))
RETURN 0
.
- Prev by Date: query timing
- Next by Date: Linux kernel tuning for Sybase ASE 12.5.x
- Previous by thread: query timing
- Next by thread: Linux kernel tuning for Sybase ASE 12.5.x
- Index(es):
Relevant Pages
|