2011-10-12 2 views
0

테이블 집합의 모든 레코드에 대해 마지막 업데이트 타임 스탬프를 유지하는 모델을 찾고 있습니다. 한 가지 아이디어는 레코드를 업데이트 한 방법에 관계없이 DateLastUpdated 열이 최신 상태로 유지되도록 트리거를 사용하여 구현하는 것이 었습니다.마지막 업데이트 날짜를 추적하기위한 트리거 업데이트 (SQL 2008 R2)

Data_Updata라는 테스트 테이블이 있으면이 데이터는 데이터가 업데이트되도록하는 현재 업데이트 트리거입니다. 이를 실행할 때 쿼리 실행 계획을 살펴보면 트리거는 56 %의 시간이 걸립니다. 거기에 더 효율적인 트리거/SQL 사용할 수 있습니까?

ALTER TRIGGER [dbo].[Data_Update] 
    ON [dbo].[Data_Trigger] 
    FOR UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 
    UPDATE 
     [Data_Trigger] 
    SET 
     DateLastUpdated = GetDate() 
    FROM 
     [Data_Trigger] data 
    JOIN 
     inserted ON data.DataID = inserted.DataID 
END 
+0

수정이 발생한 실제 datetime을 알아야합니까, 아니면 어떤 활동을 조정하는 메커니즘으로 이것을 사용하고 있습니까 (예 : 마지막으로 본 MAX (DateLastUpdated)를 추적 한 다음 행을 요청합니다) 더 큰'DateLastUpdated') - 두 번째 SQL 서버가 자동으로 관리하는'rowversion'을 사용할 수 있습니다. –

답변

4

매우 가능성이 (가) [Data_trigger]inserted 사이에 조인 [Data_trigger] 테이블에 TABLE SCAN/CLUSTERED INDEX SCAN 사용합니다.

무엇을 할 수 있습니까? 이 트리거

확인 캐시 계획 :

1) 먼저, 개체 (트리거)에 대한 plan_handle을 찾기 위해이 쿼리를 실행 :

SELECT t.name AS TriggerName 
     ,ts.* 
FROM sys.dm_exec_trigger_stats ts 
INNER JOIN sys.triggers t ON ts.object_id = t.object_id 
WHERE ts.database_id = DB_ID() 
AND  t.name LIKE '%Audit%'; 

2) 둘째, 캐시 된 계획 (XML을 찾을 수) .

DECLARE @plan_handle VARBINARY(64) = 0x050009009A0A677BB8E09C7A000000000000000000000000; 
SELECT * 
FROM sys.dm_exec_query_plan(@plan_handle) qp; 

만약에 당신이 가지고 CLUSTERED INDEX SCAN[Data_trigger]에 대한 (적어도) 세 가지를 사용 [Data_trigger]inserted 사이에 조인이 트리거에 대한 계획 핸들이 0x050009009A0A677BB8E09C7A000000000000000000000000 경우 예를 들어, 캐시 된 계획을 찾기 위해이 쿼리를 사용할 수 있습니다 SQL Server 2008의 옵션 :

1) UPDATE STATISTICS[Data_trigger] 테이블 : updating statistics causes queries to recompile의 옵션 이 작업 후에 테스트 트리거를 실행하고 캐시 된 계획을 확인하여 SEEK을 사용하는지 확인합니다. 이 작업, 테스트 트리거 후

FROM 
    [Data_Trigger] data 
WHERE data.DataID IN (SELECT DataID IN SELECT inserted) 

을하고 SEEK를 사용하는 경우 볼을 다시 캐시 된 계획을 확인하십시오

2) 또는 하나 개 IN 하위 쿼리를 사용하여 UPDATE에서 JOIN을 다시 작성할 수 있습니다.

3) SEEK 연산자는 use FORCESEEK table hint (new in SQL Server 2008; also see Best Practice Considerations section)을 할 수있는 다음 사용하지 않는 경우 : DataID 컬럼에 인덱스) 클러스터 또는 클러스터 (고유를 만드는

FROM 
    [Data_Trigger] data WITH(FORCESEEK) 
JOIN 
    inserted ON data.DataID = inserted.DataID 

TABLE SCAN 노력합니다.