반응형

본 포스트는 Microsoft TechNet의 [논리 및 물리 연산자 참조]내용을 참고하여 정리한 내용이다.

※실행계획 연산자 전체 보기

 

Assert 연산자는 제약 조건 확인, 참조 무결성 확인 또는 스칼라 하위 쿼리(Scalar Subquery)에서 한 개의 행만 반환하는지 등 상태 검증을 이행할 때 나타나는 물리 연산자이다. 

 

Assert 연산자는 각 입력 행에 대해 실행 계획의 Argument 열의 식을 계산하게 되는데, 이 식의 결과 값이 NULL이면, 그 행은 Assert 연산자를 통과해서 쿼리 실행을 계속하게 된다. 이 식이 NULL이 아니면 해당 오류가 발생한다.

 

그래프 실행계획 아이콘


 

예제

1. CHECK 제약 조건의 유효성 검사

다음 예에서는 HumanResources.Employee 테이블에서 지정한 직원의 ID에 대해 Gender 열의 값을 갱신한다. 이 테이블에는 열에 'F' 및 'M' 값만 허용하는 CHECK 제약 조건(CK_Employee_Gender)이 있다. 쿼리 실행 계획에서는 쿼리 최적화 프로그램이 Assert 연산자를 사용하여 CHECK 제약 조건에 대해 UPDATE 문에서 지정한 값의 유효성을 검사하고, 제약 조건의 조건이 충족되지 않을 때 오류를 발생시킴을 보여준다.

USE AdventureWorks
GO
SET NOCOUNT ON
GO
SET SHOWPLAN_ALL ON
GO
UPDATE HumanResources.Employee
    SET Gender = 'X'
  WHERE EmployeeID = 1
GO
SET SHOWPLAN_ALL OFF
GO

  

Assert 연산자의 실행 계획

StmtText
------------------------------------------------------------------------------------------------------------------------------
UPDATE HumanResources.Employee
SET Gender = 'X' WHERE EmployeeID = 1;
  |--Assert(WHERE:(CASE WHEN upper([AdventureWorks].[HumanResources].[Employee].[Gender])<>N'F'
                         AND upper([AdventureWorks].[HumanResources].[Employee].[Gender])<>N'M' THEN (0)
                        ELSE NULL END))
       |--Clustered Index Update(OBJECT:([AdventureWorks].[HumanResources].[Employee].[PK_Employee_EmployeeID]),
           SET:([AdventureWorks].[HumanResources].[Employee].[Gender] = RaiseIfNull([Expr1003])),
           DEFINE:([Expr1003]=CONVERT_IMPLICIT(nchar(1),[@1],0)), W


 

2. FOREIGN KEY 제약 조건의 유효성 검사

다음 예에서는 Person.Contact 테이블에서 행을 삭제한다. 이 테이블의 ContactID 열에 대해서 외래 키 참조하는 6개의 테이블이 있는데, 쿼리 실행 계획에서는 쿼리 최적화 프로그램이 Assert 연산자를 사용하여 이러한 각 제약 조건에 대해 DELETE 문의 유효성을 검사함을 보여준다.

USE AdventureWorks
GO
SET NOCOUNT ON
GO
SET SHOWPLAN_ALL ON
GO
DELETE Person.Contact WHERE ContactID = 1209
GO
SET SHOWPLAN_ALL OFF
GO

 

Assert 연산자의 실행 계획

StmtText...
----------------------------------------------------------------------------------------------------...
DELETE Person.Contact WHERE ContactID = 1209;...
  |--Sequence...
       |--Table Spool...
       |    |--Assert(WHERE:(CASE WHEN NOT [Expr1030] IS NULL THEN (0) ELSE CASE WHEN NOT [Expr1031]...
       |         |--Nested Loops(Left Semi Join, OUTER REFERENCES:([AdventureWorks].[Person].[Contac...
       |              |--Nested Loops(Left Semi Join, OUTER REFERENCES:([AdventureWorks].[Person].[C...
       |              |    |--Nested Loops(Left Semi Join, OUTER REFERENCES:([AdventureWorks].[Perso...
       |              |    |    |--Nested Loops(Left Semi Join, OUTER REFERENCES:([AdventureWorks].[...
       |              |    |    |    |--Nested Loops(Left Semi Join, OUTER REFERENCES:([AdventureWor...
       |              |    |    |    |    |--Nested Loops(Left Semi Join, OUTER REFERENCES:([Adventu...
       |              |    |    |    |    |    |--Clustered Index Delete(OBJECT:([AdventureWorks].[P...
       |              |    |    |    |    |    |--Clustered Index Scan(OBJECT:([AdventureWorks].[Sal...
   …


 

※예제에서 확인할 수 있듯이, 제약 조건을 사용하게 되면 Assert 연산자의 추가 비용이 발생한다. 특히 FOREIGN KEY 제약 조건을 설정했을 경우  위의 두 번째 예처럼 참조 무결성을 체크하기 위해 Join 연산을 수행하게 된다.

반응형

+ Recent posts