Trigger e la funzione UPDATE()
Oggi parliamo di trigger e piΓΉ nello specifico della funzione UPDATE() e piΓΉ in generale di come ottimizzare questi automatismi che SQL Server mette a disposizione.
Partiamo dalla funzione UPDATE() per parlare delle metatabelle INSERTED e DELETED.
Buona lettura!
La funzione UPDATE()
GiΓ , ma che cos’Γ¨ la funzione UPDATE()?
La funzione UPDATE(NOMECOLONNA), che si utilizza dentro ad un trigger restituisce l’informazione relativa al fatto che il valore della campo NOMECOLONNA abbia cambiato o meno valore.
Vediamo un esempio creandoci due semplici tabelle uguali tra di loro
INSERTED & DELETED
Avrei potuto infatti scrivere così:
La funzione UPDATE(NOMECOLONNA), che si utilizza dentro ad un trigger restituisce l’informazione relativa al fatto che il valore della campo NOMECOLONNA abbia cambiato o meno valore.
Vediamo un esempio creandoci due semplici tabelle uguali tra di loro
CREATE table TABELLA_A (id int identity (1,1), CODICE VarChar(40), DESCR VarChar(40))
CREATE table TABELLA_B (id int identity (1,1), CODICE VarChar(40), DESCR VarChar(40))
Adesso creiamo un trigger in update sulla tabella_A per ottenere questo comportamento:
Se cambia il codice nella tabelle_A allora cambierΓ il codice nella tabella_B
CREATE TRIGGER [dbo].[TR_TABELLA_A_UPD_CODICE] ON [dbo].[TABELLA_A]
AFTER UPDATE
AS
IF UPDATE(CODICE)
BEGIN
UPDATE L
SET L.CODICE = I.CODICE
FROM INSERTED I
JOIN DELETED D on I.ID = D.ID
JOIN TABELLA_B L on L.CODICE = D.CODICE
END
Come potete vedere ho l’utilizzato l’IF UPDATE(). Ma perchΓ© l’ho fatto?
….Performance sempre performance!
E qui il primo concetto:
Che motivo avrei per eseguire un update –che non aggiornerΓ nessuna riga- quando il campo codice non viene cambiato. Nessuna!
Quindi le prime ottimizzazioni partono dall’evitare un esecuzione inutile.
INSERTED & DELETED
Sfruttare IF UPDATE non Γ¨ perΓ² l’unico modo di ottenere questo risultato.
L’altro metodo Γ¨ quello di interrogare le tabelle INSERTED e DELETED.
CREATE TRIGGER [dbo].[TR_TABELLA_A_UPD_CODICE] ON [dbo].[TABELLA_A]
AFTER UPDATE
AS
IF EXISTS (SELECT I.ID FROM INSERTED I JOIN DELETED D ON I.ID = D.ID WHERE I.CODICE = D.CODICE)
BEGIN
UPDATE L
SET L.CODICE = I.CODICE
FROM INSERTED I
JOIN DELETED D ON I.ID = D.ID
JOIN TABELLA_B L ON L.CODICE = D.CODICE
END
Ma quale differenza c’Γ¨ tra questi due modi di procedere?
Vediamole eseguendo questa Query con il trigger che utilizza IF UPDATE
UPDATE [TABELLA_A] SET CODICE = '012' WHERE id = 1
Osserviamo il piano di esecuzione:
Cosa notate?
Nel piano di esecuzione l’ IF UPDATE non lo vedo. Quindi come metodo sembra ottimo in quanto non impiega ne tempo ne risorse.
Però attenzione: perché è così veloce?
La funzione UPDATE()
Γ¨ cosΓ¬ veloce perchΓ© non fa altro che cercare se l’update che state
eseguendo contiene “la parola” CODICE. (E questo Γ¨ il secondo concetto da ricordare)
Quindi, se la velocitΓ Γ¨ il PRO, Il CONTRO deriva proprio da quello che abbiamo appena detto.
La funzione UPDATE()
ritorna TRUE anche se effettivamente non viene aggiornato nessun dato:
se ci fate caso le due tabelle che abbiamo creato sono vuote.
Per completare l’argomento facciamo il confronto con il trigger che impiega l’interrogazione delle tabelle INSERTED e DELETED.
Il nostro piano di esecuzione diventa così:
Innanzitutto questa volta nel piano di esecuzione l’istruzione IF EXISTS (SELECT I.ID FROM INSERTED I JOIN DELETED D ON I.ID = D.ID WHERE I.CODICE = D.CODICE) la vediamo (tra l’altro questa SELECT impiega il 65 % del tempo totale)
Per terminare, oggi vi ho raccontato "un bel po di cose" sulla funzione UPDATE().
Abbiamo visto come utilizzarla nei trigger, abbiamo capito come funziona e anche perché è così veloce.
Abbiamo poi confrontato questo modo di procedere con un modo alternativo che consiste nell’interrogare le tabelle INSERTED e DELETED.
Per oggi Γ¨ tutto.
Ciao ed alla prossima!
Luca
Luca Biondi @ SQLServerPerformance blog!Next post: SET IDENTITY_INSERT, a cosa serve?
Previous post: Di sottoquery ed ottimizzazioni (parte 2)

Comments
Post a Comment