Collapse 연산자는 논리/물리 연산자로써, 업데이트 처리를 최적화할 때 나타나는 연산자이다.
그리고 Split 실행 계획 연산자라는 것이 있는데 Collapse 실행 계획 연산자와 함께 업데이트 처리를 최적화하는데 상호작용한다.
Split 실행 계획 연산자는 논리/물리 연산자로써, 각 업데이트 작업을 삭제 및 삽입 작업으로 분할한다.
그래프 실행 계획 아이콘
Collapse 실행 계획 연산자 Split 실행 계획 연산자
Collapse 논리/물리 연산자에 대해 BOL의 내용을 인용하면 "쿼리 프로세서가 동일한 키 값을 삭제 및 삽입하는 인접 행을 발견하면 별개의 두 작업을 보다 효율적인 한 개의 업데이트 작업으로 교체한다" 라고 되어 있다.
역시 어렵다... ㅡ.ㅡ
언제나 느끼는 것이지만 BOL을 해석하는 것은 어렵다 ㅜ.ㅜ
이를 쉽게 설명하자면,
- 인용문에서 "쿼리 프로세서가 동일한 키 값을 삭제 및 삽입하는 인접 행을 발견하면" 이란 "두 개 이상의 인접한 인덱스 키 값을 업데이트 할 때..." 로
- 인용문에서 "별 개의 두 작업을..." 은 "업데이트할 열 들(즉 열 하나하나가 작업이다)" 로
- 인용문에서 "보다 효율적인 한 개의 업데이트 작업으로 교체한다" 란 "두 개 이상의 업데이트 열을 한 번의 업데이트 작업으로 바꾸어 처리한다" 라는
의미로 해석하면 이해가 빠르지 않을까 싶다.
즉, "두 개 이상의 인접한 인덱스 키 값을 업데이트할 때, 한 행 한 행 업데이트하는 것이 아니라, 쿼리 프로세스가 내부적으로 하나의 업데이트 프로세스로 처리한다" 라는 것이다.
이에 대해 좀 더 부연 설명하도록 하겠다. ^^;
행을 업데이트 할 때, MS SQL Server의 쿼리최적화기(Query Optimizer)는 타 RDMBS의 비용기반 쿼리최적화기(Cost Based Optimizer)와 마찬가지로 여러가지 업데이트 전략 중에서 가장 빠르게 업데이트 할 수 있는 방법을 스스로 판단하고 선택한다.
이 때 얼마나 많은 행을 업데이트하느냐? 어떤 방법으로 행에 엑세스 하느냐(Scan을 하느냐? Seek를 하느냐? 인덱스를 사용한다면 어떤 인덱스를 사용하느냐?)? 인덱스 키를 업데이트 하느냐? 등을 고려하여 전략을 수립한다.
특히 인덱스 키를 업데이트할 경우, 그 중에서 인접한 복수의 행을 업데이트할 경우, Collapse 연산자가 나타나게 되는데, Collapse 연산자는 업이 때 발생하는 행의 이동을 행 단위가 아닌 하나의 프로세스로 처리한다.
다시 말해, 1행과 2행을 업데이트 할 때
Update 1행...
Update 2행...
이 아닌,
Update 1,2행
이런 식으로 일괄(Grouping) 처리하는 것이다 (아래에 예를 통해서 설명하겠지만, Collapse의 연산자의 실행 계획의 Argument 열에서 GROUP BY가 나타나는 것을 유심히 관찰해 보기 바란다).
그리고 이 때, 업데이트할 행들은 Split 연산자에 의해 삽입과 삭제 두 과정으로 나뉘어져서 Collapse 연산자의 Argument로 공급된다.
1. 클러스터형 인덱스 키가 있는 열을 업데이트할 경우의 Collapse 연산자의 예
이해를 돕기 위해 아래와 같이 dbo.CollapseTest1이라는 테이블을 만들고 col1에 클러스터형 인덱스를 작성해 보도록 하겠다.
CREATE TABLE dbo.CollapseTest1
GO
SELECT * FROM dbo.CollapseTest1
col1 col2 |
이제 클러스터형 인덱스가 있는 col1에 대해 업데이트를 하고 실행 계획을 살펴보도록 하자.
단, col1은 한 행이 아닌 인접해 있는 복수 개의 행을 업데이트해야 Collapse 연산자가 나타난다.
SET NOCOUNT ON
SET SHOWPLAN_ALL ON
UPDATE dbo.CollapseTest1 SET col1 = col1 + 10 WHERE col1 BETWEEN 1 and 3 GO
SET SHOWPLAN_ALL OFF |
텍스트 실행 계획
SttText |
UPDATE dbo.CollapseTest1 SET col1 = col1 + 10 WHERE col1 BETWEEN 1 and 3 , SET:([TestDB].[dbo].[CollapseTest1].[col1] = RaiseIfNull([TestDB].[dbo].[CollapseTest1].[col1]) ,[TestDB].[dbo].[CollapseTest1].[col2] = [TestDB].[dbo].[CollapseTest1].[col2])) , SEEK:([TestDB].[dbo].[CollapseTest1].[col1] >= (1) AND [TestDB].[dbo].[CollapseTest1].[col1] <= (3)) ORDERED FORWARD) |
그래픽 실행 계획
|
실행계획의 설명
- Clustered Index Seek : 업데이트할 행을 CollapseTest1_PK 인덱스를 검색한다. 이 때 SEEK 조건자는 1 <= col1 <= 3 이다.
- Compute Scalar : 업데이트할 데이터 값을 계산한다. 업데이트할 값은 col1 + 10 이다.
- Split : 업데이트 할 데이터를 각각 삭제와 삽입의 작업으로 분할한다. 즉, 11, 12, 13, 14는 새로운 삽입 작업이고, 1,2,3,4는 삭제 작업이다.
- Sort : Split에 의해 분리된 작업을 작업이 편하게 정렬한다.
- Collapse : 정렬된 Argument 열 목록을 그룹핑하여 일괄처리 작업을 만든다.
- Clustered Index Update : 마지막으로 해당 열을 업데이트한다.
그렇다면, 넌클러스터형 인덱스 키가 있는 열을 업데이트할 경우, 어떤 실행계획이 나타날까?
한 번 테스트해 보길 바란다.