2012-03-28 11 views
6

Mi chiedevo se ci fosse qualche differenza di prestazioni tra i due approcci di seguito. Fondamentalmente, il problema è che consentiamo spazi e trattini in un ID, ma alcune applicazioni legacy non sono in grado di utilizzarle in modo che vengano eliminate. Per quanto posso vedere il modo migliore per farlo è in un trigger o come una colonna calulated. L'SQL è mostrato sotto (ripulito e reso anonimo così da scusarsi se si è verificato un errore) Finora sui nostri server di test, non sembra esserci alcuna differenza tra i due metodi, qualcun altro ha qualche input?Invece Trigger o colonna calcolata? che è migliore?

[database di SQL Server 2008] [Tabella di ricerca 20000000 righe e crescente]

Opzione 1 - Creare grilletto

CREATE TRIGGER triMem_Lkup on Mem_Lkup 
INSTEAD OF INSERT 
AS 
BEGIN 
    INSERT INTO Mem_lkup 
     SELECT ex_id, contact_gid, id_type_code, date_time_created, 
       (replace(replace([ex_id],' ',''),'-','')) as ex_id_calc 
     FROM inserted 
END 
GO 

Versus Opzione 2 - utilizzare una colonna calcolata

CREATE TABLE [dbo].[Mem_lkup](
    [mem_lkup_sid] [int] IDENTITY(1,1) NOT NULL, 
    [ex_id] [varchar](18) NOT NULL, 
    [contact_gid] [int] NOT NULL, 
    [id_type_code] [char] (1) NOT NULL, 
    [date_time_created] [datetime] NOT NULL, 
    [ex_id_calc] AS CAST(replace(replace([ex_id],' ','') ,'-','') AS varchar(18)) PERSISTED 

    CONSTRAINT [PK_Mem_Lkup] PRIMARY KEY NONCLUSTERED 
(
    [mem_lkup_sid] ASC 
) 

Qual è il migliore?

risposta

4

Le colonne calcolate saranno le migliori.

Il trigger INSTEAD OF creerà prima l'intera tabella pseudo inserted in tempdb.

Plan

Per la versione di attivazione con il CREATE TABLE economico (non PK cluster su un mucchio)

SET STATISTICS IO ON; 

INSERT INTO [_test].[dbo].[Mem_lkup] 
      ([ex_id] 
      ,[contact_gid] 
      ,[id_type_code] 
      ,[date_time_created]) 
SELECT type AS [ex_id] 
     ,1 [contact_gid] 
     ,'A' [id_type_code] 
     ,getdate() [date_time_created] 
    FROM master..spt_values 

Mi dà

Table 'Worktable'. Scan count 0, logical reads 5076 
Table 'spt_values'. Scan count 1, logical reads 15 

Table 'Mem_lkup'. Scan count 0, logical reads 7549 
Table 'Worktable'. Scan count 1, logical reads 15 

considerando che la versione colonna calcolata è simile ma evita le letture worktable.

Table 'Mem_lkup'. Scan count 0, logical reads 7555 
Table 'spt_values'. Scan count 1, logical reads 15 

C'è qualche ragione per cui si continua a perseguire questo valore? (invece di avere una colonna calcolata non persistente)

+0

Ho pensato che avrei dovuto mantenere la colonna calcolata poiché viene usata come parte di un indice. (http://msdn.microsoft.com/en-us/library/ms189292.aspx#BKMK_persisted) Non è corretto? –

+0

@EoinO - No. Non per questo caso, solo per valori imprecisi (float) o funzioni/tipi CLR. –

+1

Grazie a @Martin, le tue risposte sono state davvero istruttive! Ri: commento persistente, se si stanno eseguendo migliaia di record, questo valore dovrebbe essere calcolato ogni volta? –