Unix Technical Forum

Optimizar stored procedure

This is a discussion on Optimizar stored procedure within the Sybase forums, part of the Database Server Software category; --> Buenas Tardes: Alguien me podria decir como puedo hacer este stored procedure mas rapido?? estoy usando SYBASE y tarda ...


Go Back   Unix Technical Forum > Database Server Software > Sybase

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 06-02-2008, 12:34 PM
mbgbrown1@hotmail.com
 
Posts: n/a
Default Optimizar stored procedure

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
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 06-13-2008, 02:00 PM
Philipp Post
 
Posts: n/a
Default Re: Optimizar stored procedure

> Alguien me podria decir como puedo hacer este stored procedure mas rapido?? <

Check if you can replace creating temp tables by views or a simple
SELECT statement and avoid cursors as they create performance
bottlenecks - in most cases there is a set oriented solution possible.

brgds

Philipp Post
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:23 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com