SQL Server 쿼리 처리 아키텍처 _ SQL 문 처리 (2/4)

– 뷰(View) 확인

 

  • Version : SQL Server 2005, 2008, 2008R2, 2012

 

SQL Server 쿼리 프로세서에서는 인덱싱된 뷰와 인덱싱 되지 않은 뷰가 다르게 처리 된다.

인덱싱된 뷰의 행은 테이블과 동일한 형식으로 데이터베이스에 저장 된다. 쿼리 프로세서에서 쿼리 계획에 인덱싱된 뷰를 사용하기로 결정하면 인덱싱된 뷰는 기본 테이블과 동일한 방법으로 처리 된다.

인덱싱되지 않은 뷰는 뷰의 정의만 저장되고 뷰의 행은 저장되지 않는다. 쿼리 최적화 프로그램은 인덱싱되지 않은 뷰를 참조하는 SQL문에 대해 작성하는 실행 계획에 뷰 정의의 논리를 추가 한다.

 

SQL Server 쿼리 최적화 프로그램에서 인덱싱된 뷰의 사용 여부를 결정하는 논리는 테이블 인덱스를 결정하는 데 사용되는 논리와 유사하다. SQL문 전체나 일부가 인덱싱된 뷰의 데이터를 포괄하고 해당 뷰의 인덱스가 저렴한 비용의 액세스 경로로 확인되면 쿼리의 이름이 이 뷰를 참조하는지 여부와 관계 없이 인덱스가 선택 된다.

 

SQL 문에서 인덱싱되지 않은 뷰를 참조할 경우 파서와 쿼리 최적화 프로그램은 SQL문의 원본과 뷰의 원본을 모두 분석하고 단일 실행계획을 세운다.

SQL문과 뷰의 별도 실행 계획이 있는 것은 아니다.

 

[뷰 생성]

USE AdventureWorks2008R2;

GO

CREATE VIEW EmployeeName AS

SELECT h.BusinessEntityID, p.LastName, p.FirstName

FROM HumanResources.Employee AS h

JOIN Person.Person AS p

ON h.BusinessEntityID = p.BusinessEntityID;

GO

 

 

 

[뷰를 사용한 실행 계획]

위에서 생성한 뷰를 기반으로 아래 스크립트에서 두 SQL문이 모두 기본 테이블에 대해 동일한 작업을 수행하고 동일한 결과를 생성한다.

/* SELECT referencing the EmployeeName view. */

SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate

FROM AdventureWorks2008R2.Sales.SalesOrderHeader AS soh

JOIN AdventureWorks2008R2.dbo.EmployeeName AS EmpN

ON (soh.SalesPersonID = EmpN.BusinessEntityID)

WHERE OrderDate > '20020531';

 

 

 

/* SELECT referencing the Person and Employee tables directly. */

SELECT LastName AS EmployeeLastName, SalesOrderID, OrderDate

FROM AdventureWorks2008R2.HumanResources.Employee AS e

JOIN AdventureWorks2008R2.Sales.SalesOrderHeader AS soh

ON soh.SalesPersonID = e.BusinessEntityID

JOIN AdventureWorks2008R2.Person.Person AS p

ON e.BusinessEntityID =p.BusinessEntityID

WHERE OrderDate > '20020531';

 

 

 

[뷰 힌트]

쿼리의 뷰에 힌트를 넣으면 뷰가 확장되어 기본 테이블에 액세스할 때 발견되는 다른 힌트와 서로 충돌 할 수 있다. 이경우 쿼리에서 오류를 반환 한다.

 

다음 예제 스크립트는 뷰에 적용된 SERIALIZABLE 힌트가 뷰 확장시 원본 테이블의 Person.Address, Person.StateProvince 테이블에 모두 전파되기 때문에 이 쿼리는 Person.Address의 LOCK 힌트와 충돌로 인하여 오류를 반환 한다.

 

아래 스크립트는 뷰 생성시 NOLOCK 힌트를 사용하였다.

--CREATE VIEW

CREATE VIEW Person.AddrState WITH SCHEMABINDING AS

SELECT a.AddressID, a.AddressLine1,

s.StateProvinceCode, s.CountryRegionCode

FROM Person.Address a WITH (NOLOCK), Person.StateProvince s

WHERE a.StateProvinceID = s.StateProvinceID;

 

아래 스크립트는 데이터 조회 시 NOLOCK이 사용하여 생성된 뷰를 SERIALIZABLE 힌트를 사용하여 조회한 결과 이다.

SELECT AddressID, AddressLine1, StateProvinceCode, CountryRegionCode

FROM Person.AddrState WITH (SERIALIZABLE)

WHERE StateProvinceCode = 'WA';

 

 

이 외에 다양한 잠금 힌트가 서로 충돌하여 오류를 발생 한다. 중첩된 뷰의 경우에도 뷰가 확장 할 때 상속 받은 뷰는 영향을 받게 된다.

 

 

[뷰 사용과 테이블 조인 순서]

뷰를 포함하는 쿼리에 FORCE ORDER 힌트를 사용하면 정렬된 구조체에서의 뷰 위치에 따라 뷰 내의 테이블 조인 순서가 결정 된다.

-- CREATE TABLE

CREATE TABLE TBL_A(ID NVARCHAR(50),NAME NVARCHAR(50))

CREATE TABLE TBL_B(ID NVARCHAR(50),NAME NVARCHAR(50))

CREATE TABLE TBL_C(ID NVARCHAR(50),NAME NVARCHAR(50))

CREATE TABLE TBL_D(ID NVARCHAR(50),NAME NVARCHAR(50))

CREATE TABLE TBL_E(ID NVARCHAR(50),NAME NVARCHAR(50))

CREATE TABLE TBL_F(ID NVARCHAR(50),NAME NVARCHAR(50))

GO

 

INSERT INTO TBL_A VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

INSERT INTO TBL_B VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

INSERT INTO TBL_C VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

INSERT INTO TBL_D VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

INSERT INTO TBL_E VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

INSERT INTO TBL_F VALUES ('KANG SW', 'HTTP://SQLMVP.KR')

GO

 

-- CREATE VIEW

CREATE VIEW VIEW1 AS

SELECT C.ID, D.NAME

FROM TBL_C AS C INNER JOIN TBL_D AS D

ON C.ID = D.ID

 

 

 

 

실행 결과 쿼리 계획에서 조인 순서는 TBL_A, TBL_B, VIEW1, TBL_E, TBL_F로 실행 된 것을 확인 할 수 있다.

 

 

[참고 자료]

http://msdn.microsoft.com/ko-kr/library/ms190237(v=sql.105).aspx

http://msdn.microsoft.com/ko-kr/library/ms187864(v=sql.105).aspx

http://sqlmvp.kr/140181977090



강성욱 / jevida@naver.com
Microsoft SQL Server MVP
Blog : http://sqlmvp.kr
Facebook : http://facebook.com/sqlmvp

No. Subject Author Date Views
Notice 2023년 1월 - SQLER의 업데이트 강좌 리스트 코난(김대우) 2023.01.02 599
1786 메모리 관리 아키텍처 – 프로세스 주소 공간 jevida(강성욱) 2016.09.28 1386
1785 메모리 관리 아키텍처 – 메모리 아키텍처 jevida(강성욱) 2016.09.28 1911
1784 데이터 압축 상태에 대한 개체 크기 예상 jevida(강성욱) 2016.09.28 1398
1783 sp_MSforeachdb, sp_MSforeachtable 프로시저 활용하기 jevida(강성욱) 2016.09.28 3092
1782 SQL Server 쿼리 처리 아키텍처_분산 쿼리 아키텍처 jevida(강성욱) 2016.09.28 1180
1781 SQL Server 쿼리 처리 아키텍처_병렬 쿼리 처리 - 병렬 인덱스 작업 jevida(강성욱) 2016.09.28 1380
1780 SQL Server 쿼리 처리 아키텍처_병렬 쿼리 처리 - 병렬 처리 수준 jevida(강성욱) 2016.09.28 1924
1779 SQL Server 쿼리 처리 아키텍처_병렬 쿼리 처리 jevida(강성욱) 2016.09.28 1813
1778 SQL Server 쿼리 처리 아키텍처_실행 계획 캐싱 및 다시 사용 - Preparing SQL Statements jevida(강성욱) 2016.09.28 1037
1777 SQL Server 쿼리 처리 아키텍처_실행 계획 캐싱 및 다시 사용 - 강제 매개 변수화 jevida(강성욱) 2016.09.28 1021
1776 SQL Server 쿼리 처리 아키텍처_실행 계획 캐싱 및 다시 사용 - 단순 매개 변수화 jevida(강성욱) 2016.09.28 909
1775 SQL Server 쿼리 처리 아키텍처_실행 계획 캐싱 및 다시 사용 - 매개 변수 및 실행 계획 재사용 jevida(강성욱) 2016.09.28 1135
1774 SQL Server 쿼리 처리 아키텍처_실행 계획 캐싱 및 다시 사용 jevida(강성욱) 2016.09.28 1460
1773 DMV를 이용한 캐시된 저장 프로시저 통계 정보 확인 jevida(강성욱) 2016.09.28 1029
1772 SQL Server 쿼리 처리 아키텍처_저장 프로시저 및 트리거 실행 jevida(강성욱) 2016.09.27 966
1771 SQL Server 쿼리 처리 아키텍처 _ SQL 문 처리 (4/4) – 분산형 분할 뷰(View) 확인 jevida(강성욱) 2016.09.27 1365
1770 SQL Server 쿼리 처리 아키텍처 _ SQL 문 처리 (3/4) – 뷰(View)의 인덱스 확인 jevida(강성욱) 2016.09.27 993
» SQL Server 쿼리 처리 아키텍처 _ SQL 문 처리 (2/4) – 뷰(View) 확인 jevida(강성욱) 2016.09.27 1465
1768 SQL Server 쿼리 처리 아키텍처 _ SQL 문 처리 (1/4) – SQL 문 최적화 및 Worktables jevida(강성욱) 2016.09.27 953
1767 SQL Server DMV를 이용한 통계 정보 확인 jevida(강성욱) 2016.09.27 1780





XE Login