2012-03-28 21 views
6

Me preguntaba si había alguna diferencia de rendimiento entre los dos enfoques a continuación. Básicamente, el problema es que permitimos espacios y guiones en una identificación, pero ciertas aplicaciones heredadas no pueden usarlas para que se eliminen. Por lo que puedo ver, la mejor forma de hacerlo es en un desencadenante o en una columna calificada. El SQL se muestra a continuación (limpiado y anonimizado así que le pedimos disculpas si se deslizó un error) Hasta ahora en nuestros servidores de prueba, no parece haber ninguna diferencia entre los dos métodos, ¿alguien más tiene alguna entrada?¿En su lugar desencadenador o columna calculada? ¿cual es mejor?

[base de datos SQL Server 2008] [Tabla de consulta 20000000 filas y en crecimiento]

Opción 1 - Crear gatillo

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 Opción 2 - Se utiliza una columna calculada

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 
) 

¿Cuál es el mejor?

Respuesta

4

Las columnas calculadas serán las mejores.

El disparador INSTEAD OF creará toda la tabla pseudo inserted en tempdb primero.

Plan

Para la versión gatillo con el CREATE TABLE declaración (no PK agrupada en un montón)

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 

me da

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 

Mientras que la versión columna calculada es similar, pero no ofrece el worktable dice.

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

¿Hay alguna razón por la que aún persiste este valor? (en lugar de tener una columna calculada no persistente)

+0

Pensé que tenía que mantener la columna calculada, ya que se está utilizando como parte de un índice. (http://msdn.microsoft.com/en-us/library/ms189292.aspx#BKMK_persisted) ¿No es eso correcto? –

+0

@EoinO - No. No para este caso, solo para valores imprecisos (float) o funciones/tipos CLR. –

+1

Gracias @Martin, ¡Sus respuestas han sido realmente informativas! Re: comentario persistido, si está ejecutando miles de registros, ¿se calcularía este valor cada vez? –

Cuestiones relacionadas