2012-03-28 10 views
6

Ich frage mich, ob es einen Leistungsunterschied zwischen den zwei Ansätzen unten gab. Das Problem ist, dass wir Leerzeichen und Bindestriche in einer ID zulassen, aber bestimmte Legacy-Anwendungen können diese nicht verwenden, sodass sie entfernt werden. Soweit ich sehen kann, ist der beste Weg, dies zu tun, entweder in einem Trigger oder als eine berechnete Spalte. Die SQL ist unten gezeigt (aufgeräumt und anonymisiert, also Entschuldigung, wenn sich ein Fehler eingeschlichen hat) Bisher scheint es auf unseren Testservern keinen Unterschied zwischen den beiden Methoden zu geben, hat sonst noch jemand etwas zu tun?Statt Trigger oder berechnete Spalte? Welches ist besser?

[Datenbank SQL Server 2008] [Lookup-Tabelle 20000000 Zeilen und wachsende]

Option 1 - Erstellen Sie Trigger

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 Option 2 -

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 
) 
eine berechnete Spalte verwenden

Welches ist das Beste?

Antwort

4

Berechnete Spalten werden am besten sein.

Der INSTEAD OF Trigger erstellt zuerst die gesamte Pseudo inserted Tabelle in tempdb.

Plan

Für die Trigger-Version mit Ihrer CREATE TABLE Anweisung (nicht gruppierten PK auf einem Haufen)

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 

mich gibt

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 

Während die berechnete Spalte Version ist ähnlich, aber vermeidet die worktable liest.

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

Gibt es einen Grund, warum Sie diesen Wert überhaupt beibehalten? (im Gegensatz zu einer nicht persistenten berechneten Spalte)

+0

Ich dachte, dass ich die berechnete Spalte beibehalten musste, da sie als Teil eines Index verwendet wird. (http://msdn.microsoft.com/en-us/library/ms189292.aspx#BKMK_persited) Ist das nicht korrekt? –

+0

@EoinO - Nein. Nicht für diesen Fall, nur für unpräzise (float) Werte oder CLR Funktionen/Typen. –

+1

Danke @Martin, Ihre Antworten waren wirklich informativ! Re: Persistent Kommentar, wenn Sie durch Tausende von Datensätzen laufen, würde dieser Wert jedes Mal berechnet werden? –

Verwandte Themen