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

Preguntas similare

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:
Mostrar la cita
#2 Gustavo Villaran
22/07/2004 - 17:41 | Informe spam
bueno seguro que es mas lenta la aplicacion,
pero que otra manera habria de hacer la auditoria?

Esta auditoria esta dentro de la aplicacion osea que el cliente
puede escoger que tabla auditar, que campos y hasta cual es
el rango que debe tener el valor del campo para ser auditado.

alguna otra idea de como hacer esto sin triggers?



"Javier Loria" wrote in message
news:%234PMQs$
Mostrar la cita
select
Mostrar la cita
multiplica
Mostrar la cita
#3 Javier Loria
22/07/2004 - 19:26 | Informe spam
Hola:
Lo importante no es que sea mas lenta sino SUSTANCIALMENTE mas lenta,
realmente crees que cuando alguien se le ocurrio: Agreguemos Auditoria, se
tomo en consideracion que podia ser que la aplicacion seria 20 veces mas
lenta!!!.
Hay muchas alternativas de Auditoria, que dependen mucho de los
objetivos que tenga. Los mas sencillos:
=(1) Opcion 1: No Denegabilidad
a) Agregar 2 columnas UsuarioInsercion y FechaInsercion, ponerles un default
SYSTEM_USER y CURRENT_TIMESTAMP.
b) Agregar 2 columnas mas UsuariosModificacion/FechaModificacion, y en el
procedimiento almacenado respectivo o en el Trigger de Update asignar los
valores.
c) Crear una Tabla Tumba que guarda la Usuario/Fecha, Tabla y Llave Primaria
de la Fila borrada.
(2) Opcion 2: Historico
a) Crear Tablas Historicas Identicas a las de Produccion + Usuario + Fecha+
Numero Consecutivo.
b) Crear una Tabla ConfiguracionAuditoria con el Nombre de la Tabla y
columna Auditable (Si/No)
c) En el procedmiento almacenado respectivo o en el Trigger Indicado
Insertar Inserted/Deleted en la Tabla.Historico. Si esta en la auditoria se
inserta respectivamente, no con un codigo super generico, uno para cada
tabla.
(3) Opcion 3: Aplicacion
a) Revisar el siguiente procedimiento:
http://www.configuracionesintegrale...p?articulo!7
(4) Opcion 4: Forense
a) Revisar el sitio de www.lumigent.com
Ninguna de estas 4 opciones impone un costo superior a 3 veces la
insercion original. Para mi un costo de 20 veces por una auditoria es un
precio demasiado alto.
Saludos,


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:
Mostrar la cita
Ads by Google
Search Busqueda sugerida