Optimizacion de Trigger

22/07/2004 - 01:31 por Gustavo Villaran | Informe spam
Hola, tengo una aplicacion hotelera la cual contempla entre otras cosas, una
replicacion de mezcla
entre 3 puntos y un sistema de auditoria de tablas que funciona con
triggers, los triggers de update y
delete se hicieron de tal manera que son iguales para todas las tablas
excepto por un parametro.

Lo que necesito es una opinion sobre si este trigger se puede optimizar, si
ahora esta mal antes
estaba peor, cada update a la tabla demoraba entre 1.5 a 3 segundos, ahora
demora entre 200 y
350 ms.

si alguien me puede dar su opinion me seria de gran ayuda.

muchas gracias

PD .Ejemplo de trigger de update de una tabla rsc_reserv :

CREATE TRIGGER ut_i_regusr_RSC_RESERV_U ON dbo.RSC_RESERV FOR UPDATE
NOT FOR REPLICATION
AS
DECLARE @li_id_proceso integer,
@ls_codhot varchar(3),
@ls_codalm varchar(3),
@ls_usuari varchar(8),
@ls_codtab char(15),
@ls_codcam char(15),
@ln_indins integer,
@ln_indmod integer,
@ln_indeli integer,
@ln_indran integer,
@ln_valmin integer,
@ln_valmax integer,
@ls_operac char(9),
@ls_deslla varchar(200),
@ls_cadena_clave nvarchar(200),
@ldt_fecha datetime,
@li_numreg integer,
@ls_sentencia_del nvarchar(100),
@ls_sentencia_ins nvarchar(100),
@ls_apos varchar(1),
@lastID integer,
@nextID integer,
@actualID integer,
@texto nvarchar(500),
@ok char(1)
BEGIN
select @ls_apos = char(39)
select @ldt_fecha = getdate()
select @texto=''

select * into #1del from deleted
select * into #1ins from inserted

exec usp_u_id_proceso @li_id_proceso output

obtener los valores del hotel y de la localidad
select @ls_codhot = ist_codhot, @ls_codalm = ist_codalm, @ls_usuari ist_usuari
from CMT_INGSIS
where ist_iningr = @li_id_proceso

select @ls_deslla = ttm_deslla
from cmm_tabtab
where ttm_codtab = 'RSC_RESERV'

select @ls_cadena_clave = N'select @result=' + @ls_deslla + ' from #1del '

exec sp_executesql @ls_cadena_clave ,N'@result nvarchar(500) output',
@texto output
select @ls_cadena_clave = @texto

if (select count(*) from cmm_paraud where htc_codhot = @ls_codhot and
pau_codloc = @ls_codalm and pau_codtab = 'RSC_RESERV' and pau_chkeli = 0 and
pau_indmod = 1) > 0
begin
select @ls_operac = 'ACTUALIZA'

select @nextID = MIN(PAU_CODPAU), @lastID = MAX(PAU_CODPAU)
from cmm_paraud
where htc_codhot = @ls_codhot and pau_codloc = @ls_codalm and pau_codtab
= 'RSC_RESERV' and pau_chkeli = 0 and pau_indmod = 1

WHILE @nextID < = @lastID
BEGIN

if @nextID > @lastID
begin
break
end

select @ActualID = PAU_CODPAU,
@ls_codtab = PAU_CODTAB,
@ls_codcam = PAU_CODCAM,
@ln_indins = PAU_INDINS,
@ln_indmod = PAU_INDMOD,
@ln_indeli = PAU_INDELI,
@ln_indran = PAU_INDRAN,
@ln_valmin = PAU_VALMIN,
@ln_valmax = PAU_VALMAX
from cmm_paraud
where htc_codhot = @ls_codhot and pau_codloc = @ls_codalm and
pau_codtab = 'RSC_RESERV' and pau_chkeli = 0 and pau_indmod = 1 and
pau_codpau = @nextID

los campos auditables
select @ls_sentencia_del = N'select @result=' + @ls_codcam +' from
#1del'
exec sp_executesql @ls_sentencia_del ,N'@result nvarchar(500)
output', @texto output
select @ls_sentencia_del = @texto

campos auditables
select @ls_sentencia_ins = N'select @result=' + @ls_codcam +' from
#1ins'
exec sp_executesql @ls_sentencia_ins ,N'@result nvarchar(500)
output', @texto output
select @ls_sentencia_ins = @texto

select @li_numreg = (select isnull(max(RUR_NUMREG),0) + 1 from
CMR_REGUSR)
select @ok = '0'
if @ln_indran = 1
if @ls_sentencia_ins >= @ln_valmin and @ls_sentencia_ins <@ln_valmax
select @ok='1'
else
select @ok='0'
else
select @ok='1'
if @ok='1'
begin
INSERT INTO CMR_REGUSR (HTC_CODHOT, ALM_CODALM, RUR_NUMREG,
RUR_DATANT, RUR_USUARI, RUR_TABAFE, RUR_CAMTAB, RUR_CLAREG,
RUR_FECREG, RUR_OPERAC, RUR_DATACT,
RUR_CHKELI, RUR_CLAVAL,RUR_INDRAN,RUR_VALMAX,RUR_VALMIN)
EXEC ('SELECT ' + @ls_apos + @ls_codhot + @ls_apos + ', ' +
@ls_apos + @ls_codalm + @ls_apos + ', ' + @li_numreg + ', ' + @ls_apos +
@ls_sentencia_del + @ls_apos + ', ' +
@ls_apos + @ls_usuari + @ls_apos + ', ' + @ls_apos +
@ls_codtab + @ls_apos + ', ' + @ls_apos + @ls_codcam + @ls_apos + ', ' +
@ls_apos + @ls_deslla + @ls_apos + ', ' +
@ls_apos + @ldt_fecha + @ls_apos + ', ' + @ls_apos +
@ls_operac + @ls_apos + ', ' + @ls_apos + @ls_sentencia_ins + @ls_apos + ',
' + '0' + ', ' +
@ls_apos + @ls_cadena_clave + @ls_apos + ', ' +
@ls_apos + @ln_indran + @ls_apos + ', ' + @ls_apos + @ln_valmax + @ls_apos +
', ' + @ls_apos + @ln_valmin + @ls_apos +
' WHERE ' + @ls_apos + @ls_sentencia_ins + @ls_apos +
' <> ' + @ls_apos + @ls_sentencia_del + @ls_apos)
end
select @nextID = @nextID + 1
END
RETURN
end
END
 

Leer las respuestas

#1 Javier Loria
22/07/2004 - 16:49 | Informe spam
Hola:
Mi opinion sobre este trigger la puedes ver en el hilo Triggers y select
dinámico. En resumen, no funcionan, descomponen los programas y son
inusables.
En este caso un simple INSERT se convierte en una proceso que multiplica
por n+2 el trabajo, siendo n en numero de columnas. Si una tabla tiene 20
columnas este trigger hace 22 veces mas lento (aproximadamente)el proceso
de un insert.
Solo una opinion,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Gustavo Villaran escribio:
Hola, tengo una aplicacion hotelera la cual contempla entre otras
cosas, una replicacion de mezcla
entre 3 puntos y un sistema de auditoria de tablas que funciona con
triggers, los triggers de update y
delete se hicieron de tal manera que son iguales para todas las tablas
excepto por un parametro.

Lo que necesito es una opinion sobre si este trigger se puede
optimizar, si ahora esta mal antes
estaba peor, cada update a la tabla demoraba entre 1.5 a 3 segundos,
ahora demora entre 200 y
350 ms.

si alguien me puede dar su opinion me seria de gran ayuda.

muchas gracias

PD .Ejemplo de trigger de update de una tabla rsc_reserv :

CREATE TRIGGER ut_i_regusr_RSC_RESERV_U ON dbo.RSC_RESERV FOR UPDATE
NOT FOR REPLICATION
AS
DECLARE @li_id_proceso integer,
@ls_codhot varchar(3),
@ls_codalm varchar(3),
@ls_usuari varchar(8),
@ls_codtab char(15),
@ls_codcam char(15),
@ln_indins integer,
@ln_indmod integer,
@ln_indeli integer,
@ln_indran integer,
@ln_valmin integer,
@ln_valmax integer,
@ls_operac char(9),
@ls_deslla varchar(200),
@ls_cadena_clave nvarchar(200),
@ldt_fecha datetime,
@li_numreg integer,
@ls_sentencia_del nvarchar(100),
@ls_sentencia_ins nvarchar(100),
@ls_apos varchar(1),
@lastID integer,
@nextID integer,
@actualID integer,
@texto nvarchar(500),
@ok char(1)
BEGIN
select @ls_apos = char(39)
select @ldt_fecha = getdate()
select @texto=''

select * into #1del from deleted
select * into #1ins from inserted

exec usp_u_id_proceso @li_id_proceso output

proceso y obtener los valores del hotel y de la localidad
select @ls_codhot = ist_codhot, @ls_codalm = ist_codalm, @ls_usuari
= ist_usuari
from CMT_INGSIS
where ist_iningr = @li_id_proceso

select @ls_deslla = ttm_deslla
from cmm_tabtab
where ttm_codtab = 'RSC_RESERV'

select @ls_cadena_clave = N'select @result=' + @ls_deslla + ' from
#1del '

exec sp_executesql @ls_cadena_clave ,N'@result nvarchar(500)
output', @texto output
select @ls_cadena_clave = @texto

if (select count(*) from cmm_paraud where htc_codhot = @ls_codhot
and pau_codloc = @ls_codalm and pau_codtab = 'RSC_RESERV' and
pau_chkeli = 0 and pau_indmod = 1) > 0
begin
select @ls_operac = 'ACTUALIZA'

select @nextID = MIN(PAU_CODPAU), @lastID = MAX(PAU_CODPAU)
from cmm_paraud
where htc_codhot = @ls_codhot and pau_codloc = @ls_codalm and
pau_codtab = 'RSC_RESERV' and pau_chkeli = 0 and pau_indmod = 1

WHILE @nextID < = @lastID
BEGIN

if @nextID > @lastID
begin
break
end

select @ActualID = PAU_CODPAU,
@ls_codtab = PAU_CODTAB,
@ls_codcam = PAU_CODCAM,
@ln_indins = PAU_INDINS,
@ln_indmod = PAU_INDMOD,
@ln_indeli = PAU_INDELI,
@ln_indran = PAU_INDRAN,
@ln_valmin = PAU_VALMIN,
@ln_valmax = PAU_VALMAX
from cmm_paraud
where htc_codhot = @ls_codhot and pau_codloc = @ls_codalm and
pau_codtab = 'RSC_RESERV' and pau_chkeli = 0 and pau_indmod = 1 and
pau_codpau = @nextID

anteriores de los campos auditables
select @ls_sentencia_del = N'select @result=' + @ls_codcam
+' from #1del'
exec sp_executesql @ls_sentencia_del ,N'@result nvarchar(500)
output', @texto output
select @ls_sentencia_del = @texto

de los campos auditables
select @ls_sentencia_ins = N'select @result=' + @ls_codcam
+' from #1ins'
exec sp_executesql @ls_sentencia_ins ,N'@result nvarchar(500)
output', @texto output
select @ls_sentencia_ins = @texto

select @li_numreg = (select isnull(max(RUR_NUMREG),0) + 1
from CMR_REGUSR)
select @ok = '0'
if @ln_indran = 1
if @ls_sentencia_ins >= @ln_valmin and
@ls_sentencia_ins <= @ln_valmax
select @ok='1'
else
select @ok='0'
else
select @ok='1'
if @ok='1'
begin
INSERT INTO CMR_REGUSR (HTC_CODHOT, ALM_CODALM,
RUR_NUMREG, RUR_DATANT, RUR_USUARI, RUR_TABAFE, RUR_CAMTAB,
RUR_CLAREG, RUR_FECREG,
RUR_OPERAC, RUR_DATACT,
RUR_CHKELI, RUR_CLAVAL,RUR_INDRAN,RUR_VALMAX,RUR_VALMIN)
EXEC ('SELECT ' + @ls_apos + @ls_codhot + @ls_apos + ', '
+ @ls_apos + @ls_codalm + @ls_apos + ', ' + @li_numreg + ', ' +
@ls_apos + @ls_sentencia_del + @ls_apos + ', ' +
@ls_apos + @ls_usuari + @ls_apos + ', ' +
@ls_apos + @ls_codtab + @ls_apos + ', ' + @ls_apos + @ls_codcam +
@ls_apos + ', ' + @ls_apos + @ls_deslla + @ls_apos + ', ' +
@ls_apos + @ldt_fecha + @ls_apos + ', ' +
@ls_apos + @ls_operac + @ls_apos + ', ' + @ls_apos +
@ls_sentencia_ins + @ls_apos + ', ' + '0' + ', ' +
@ls_apos + @ls_cadena_clave + @ls_apos + ', ' +
@ls_apos + @ln_indran + @ls_apos + ', ' + @ls_apos + @ln_valmax +
@ls_apos + ', ' + @ls_apos + @ln_valmin + @ls_apos +
' WHERE ' + @ls_apos + @ls_sentencia_ins +
@ls_apos + ' <> ' + @ls_apos + @ls_sentencia_del + @ls_apos)
end
select @nextID = @nextID + 1
END
RETURN
end
END

Preguntas similares