Вместо триггера или вычисляемого столбца?что лучше? - PullRequest
8 голосов
/ 28 марта 2012

Мне было интересно, есть ли разница в производительности между двумя подходами ниже.По сути, проблема в том, что мы допускаем пробелы и тире в идентификаторе, но некоторые устаревшие приложения не могут использовать их, поэтому они удаляются.Насколько я вижу, самый удобный способ сделать это - либо в триггере, либо в вычисляемом столбце.SQL показан ниже (очищен и анонимизирован, поэтому извиняюсь, если закралась ошибка). Пока на наших тестовых серверах нет никакой разницы между этими двумя методами, есть ли у кого-нибудь еще входные данные?

[База данных SQL Server 2008] [Таблица поиска 20000000 строк и рост]

Вариант 1 - Создать триггер

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

В сравнении с Вариантом 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
)

Какой из них лучше?

1 Ответ

6 голосов
/ 28 марта 2012

Рассчитанные столбцы будут лучшими.

Триггер INSTEAD OF создаст всю псевдо inserted таблицу в tempdb первой.

Plan

Для версии триггера с оператором CREATE TABLE (не кластеризованный PK в куче)

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

Дает мне

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

Принимая во внимание, что рассчитанная версия столбца аналогична, но избегает чтения worktable.

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

Есть ли какая-то причина, по которой вы сохраняете это значение вообще? (в отличие от наличия непостоянного вычисляемого столбца)

...