Michelle A. Poolet
돈만 있다면, 인덱스된 뷰를 사용하여 쿼리를 좀 더 간단하게 작성할 수 있다.
SQL Server의 차기버전인, SQL Server 2005에는 생산성을 높여 줄 수 있는 많은 기능과 확장성이 포함되어 있으며, 특히, 데이터베이스 기반 웹 어플리케이션을 개발하는 경우라면 더욱 도움이 될 것이다. ( SQL Server 2005의 전체적인 개관에 대해서는 SQL Server 메거진의 2004년 5월호를 살펴보면 된다.) 하지만, Microsoft에서는 SQL Server 2005의 최종 릴리즈 시기를 내년 상반기로 연기하였고, 많은 소프트웨어 판매점들은 적어도 최종 릴리즈이후 약 1년정도는 신규 데이터베이스 시스템으로 이행하지 않을 것이다. 결국, 현재 사용자들은 향후 일정기간동안 좀 더 SQL Server2000의 기능을 활용하게 될 것이다.
필자는 데이터 모델링 전문가와 설계 분석가로 일하고 있다. 그래서, 필자는 본능적으로 테이블 스키마를 확인하고 이를 최적화한다. 필자의 컬럼 “Solutions By Design”을 정규적으로 읽는 독자라면, 데이터를 추가하거나 관리하기 위해, 또한 데이터에 대한 일관성을 보장하기 위해서, 테이블의 정규화가 필수적이라는 사실을 강력하게 주장한다는 것에 대해 잘 알고 있을 것이다. 정규화의 장점은 정규화되어 있는 테이블에서 데이터를 조회하기 위해 여러 개의 테이블을 조인해야 한다는 불편함보다 훨씬 더 가치있는 것이다. 또한, 잘 정규화된 데이터베이스로부터 데이터를 조회하거나, 요약보고서를 작성하기 위한 대량의 데이터를 집계작업을 수행하기 위해, 네 개 또는 다섯 개의 테이블을 조인해야 하는 작업의 부가적인 오버헤드를 제거할 수 있는 방법이 있다. 이를 위해, SQL Server엔진이 쿼리가 실행되는 시점에 매번 뷰를 동적으로 재구성하지 않도록 “실체화(materialize)”된 뷰를 만들 수 있다. 즉, 뷰가 가상 테이블이 아닌 실제 물리적인 테이블이 되는 것이다.
일반적으로 뷰는 파생된 가상 테이블이다. 뷰는 사용자를 제한할 필요가 있는 중요데이터나 민감한 데이터를 숨기기 위한 접근 통제의 목적으로 사용되기도 하고, 관련된 정보를 좀 더 가치있는 정보 컨텍스트 단위로 표현하여 데이터의 가시성을 향상시키기 위한 목적으로 사용된다. SQL Server에서는 뷰에 대한 “실체화(materialize)”를 지원하는데, 이는 뷰에 유일한 클러스터된 인덱스를 생성하는 것을 의미하며, 이러한 실체화된 뷰를 “인덱스된 뷰”라고 한다. 클러스터된 인덱스와 마찬가지로, 실체화된 뷰는 실제로 사용자 데이터를 저장하게 된다.
실체화된 뷰는 데이터베이스 세계에서는 새로운 개념이 아니다. 비록, 인덱스된 뷰가 SQL Server 2000에서부터 지원된 새로운 기능이기는 하지만, ORACLE이나 DB2와 같은, 기존 다른 데이터베이스 관리 시스템에서는 이미 오래 전부터 동일한 기능을 제공해왔다. 대용량 DBMS 공급자들은 데이터웨어하우스 시스템의 성능을 향상시키기 위해 실체화된 뷰를 개발했었다. 데이터웨어하우스 시스템을 구축하기 위해서는 기술적으로 여러가지 서로 다른 데이터 원본으로부터 하나의 대용량 데이터 저장소로 데이터를 통합하는 작업이 필요하다. 데이터 저장소에는 운영 어플리케이션에서 사용할 상세 데이터가 저장되기도 하고, 의사결정지원시스템에서 사용할 요약 데이터도 저장되기도 하며, 양쪽 모두가 동시에 저장되기도 한다. 데이터웨어하우스에서, 일반적으로 데이터는 몇 가지 차원(예를 들어, 시간, 지역, 품목 등)으로 요약되게 되며, OLAP 및 의사결정지원 어플리케이션을 통해 집계작업 처리를 처리하여 데이터 저장소에 저장하게 된다. 다음에서는 데이터웨어하우스 이외의 다른 환경에서 실체화된 뷰를 유용하게 사용하는 예제에 대해서 살펴보게 된다.
왜 실체화된 뷰를 사용하는가?
실체화된 뷰가 데이터웨어하우스의 쿼리성능향상을 위해 만들어졌다면, 왜 굳이 트랜잭션 처리 데이터베이스에 실체화된 뷰를 사용하려고 하는가에 대한 의구심을 들 수 있다. 트랜잭션 데이터베이스 설계를 하는 경우라면, 마치 스포츠카 설계자와 마찬가지로, 속도와 민첩함을 중점으로 하여 설계를 진행하게 되기 때문에, 인덱스와 같은 데이터베이스 개체를 최소화하게 되고, 결국은 성능상에 문제의 원인이 된다. 트랜잭션 처리 데이터베이스의 경우, 데이터 조회의 성능을 개선하기 위해서는 인덱스가 사용되지만, 대표적인 성공사례를 기반으로 생각하여 볼 때, 인덱스는 데이터를 삽입하거나 변경할 때 별도의 오버헤드를 발생시키기 때문에 반드시 필수적으로 필요한 경우에 한하여 생성하는 것을 권장한다. 추가적으로, 실체화된 뷰는 하나 또는 그 이상의 테이블의 복사본이라고 볼 수 있기 때문에, 데이터 저장소의 공간도 실제적으로 두 배가 소요되게 된다.
실체화된 뷰는 데이터에 매우 빠르게 접근할 수 있도록 해 준다. 일반적으로, 실체화된 뷰를 사용하여 성능상의 개선사항은 실체화된 뷰를 위해서 투자되는 비용, 예를 들어, 실체화된 뷰와 실제 테이블의 데이터를 동기화하기 위해 소요되는 여분의 디스크 공간 및 프로세서의 비용을 충분히 보상하고도 남는다. 하지만, 무조건 실체화된 뷰를 사용하여 얻은 성능상의 개선효과가 실체화된 뷰를 관리하기 위해 소요되는 디스크 공간 및 프로세서의 비용보다 더 큰 것은 아니며, 이는 상황에 따라 매우 달라질 가능성이 있다. 그래서, 실체화된 뷰를 사용할 것인지 여부를 결정하기 위해 테스트를 진행할 때, 고려할 사항을 살펴보기 위해 몇가지 예제 시나리오를 살펴보고자 한다. 인덱스된 뷰를 추가하면 데이터변경작업에 오버헤드가 발생하기 때문에, 인덱스된 뷰를 적용할 수 있는 가장 좋은 대상은 거의 정적으로 유지되다가 피크시간이 아닌 시간대에 데이터에 대한 추가 및 변경이 발생하는 테이블이 될 수 있다.
운영 데이터베이스의 데이터 요약 운영 데이터베이스의 데이터를 집계하는 작업을 할 때 시스템자원이 많이 소모된다는 것은 모두가 공감할 것이다. 이러한 집계작업에는 단순한 합계, 건수, 평균을 계산하는 것 이상의 복잡한 처리가 포함된다. SQL Server의 잠금관리자는 데이터에 대한 요청간에 균형을 유지해야 하며, 집계작업이 진행하는 동안 데이터에 대한 변경작업을 지연시킬 수 있어야 한다. 또한, 집계작업을 위한 쿼리가 실행될 때마다, 해당 레코드가 데이터 캐시에 존재하지 않는 경우에는, 하드 디스크로부터 데이터를 물리적으로 스캔하여 메모리로 올리는 작업을 수행해야 한다. 집계작업에 포함되는 데이터가 많아질수록, 좀 더 많은 물리적인 I/O가 필요하게 된다. SQL Server에는 레코드에 대한 처리작업이 완료되자마자 즉시 해당 데이터 페이지에 대한 잠금을 해제하는 것과 같은, 데이터요청에 대한 지연이 최소화될 수 있도록 하기 위한 많은 기술을 사용하고 있다. 하지만, 특히, 이미 시스템에 막대한 작업부하가 발생한 상태에서, 집계작업을 수행하는 쿼리를 실행하게 되면, 전체적인 성능저하의 원인이 될 수 있다는 것만은 확실하다.
목록 1에는 선적된 주문건에 대한 정보가 저장되어 있는, Northwind 데이터베이스의 Orders 테이블에 실체화된 요약 뷰를 생성하는 예제가 나타나 있다. 우편번호를 기준으로 주문에 대한 요약 보고서를 생성하는 것은 판매동향을 파악하기 위해 매우 유용한 정보를 제공해 줄 수 있다. 그림 1에는 목록 1의 코드를 실행시킨 결과집합의 일부가 나타나 있다. 이 요약보고서를 통해 Northwind Trader 사는 어느 우편번호 지역으로 대부분의 제품이 배송되었는지에 대해서 쉽게 분석할 수 있을 것이다.
목록 1: 요약보고서용 인덱스된 뷰 생성
다중테이블 조인의 제거. 운영 데이터베이스환경에서는, 정보를 얻기 위해 많은 테이블을 조인해야 하는 상황이 종종 발생하게 된다. 예를 들어, Northwind 데이터베이스에서 지역별 영업사원보고서를 만들기 위해서는 네 개의 테이블을 조인해야 한다. 특정 지역에 대한 사원명부를 데이터베이스에서 쿼리하거나, 특정 지역에 대한 판매권역별 영업사원 정보를 조회하는 작업은 그리 재미있는 작업은 아니지만, 꼭 필요한 작업이다. 그림 2에 나타나 있는 ERD에서 확인할 수 있듯이, Northwind 데이터베이스와 같이 매우 잘 정규화된 데이터베이스에서는, SQL Server가 필요한 데이터를 반환하기 위해 여러 테이블간의 조인 연산을 하는 과정에서 쿼리가 지연되는 문제를, 실체화된 뷰를 사용함으로써 해결할 수 있다. 목록 2의 코드에는 네 개의 테이블을 조인한 결과에 대해 실체화된 뷰를 생성하는 예제가 나타나 있다. 그림 3에는 목록 2의 코드를 실행한 결과의 일부분이 나타나 있다.
목록 2: 네 개의 테이블을 조인하는 인덱스된 뷰
계산된 컬럼을 분리하여 관리. 잘 정규화된 데이터베이스에서 준수하고 있는 원칙 중의 하나는 사용자 데이터로부터 파생된 계산된 데이터는 별도의 테이블로 저장하고 있다는 것이다. 계산된 데이터는 시스템에 매일매일 발생하는 데이터 처리건에서 집계된 데이터라 할 수 있으며, 2차적인 데이터 처리절차라고 할 수 있다. 만약, 데이터베이스에 누계정보나 합계정보를 계산하고자 하는 경우, 지속적인 재계산 작업으로 인한 오버헤드가 발생하기 때문에, 원본 데이터 테이블에 합계정보의 계산결과를 저장하지는 않을 것이다.
물론, 테이블에 계산된 컬럼을 생성할 수 있다. 하지만, 계산된 컬럼은 가상 컬럼이다. 일반적인 뷰와 같이, 계산된 결과값은 저장되지 않으며, 쿼리에 의해 해당 컬럼의 값이 요청될 때마다 SQL Server는 동적으로 해당 컬럼값을 계산하게 된다. 테이블에 행이 많지 않다면, 동적 재계산작업이 문제가 되지 않는다. 하지만, 테이블의 1GByte 이상의 대용량인 경우, 매우 심각한 성능상의 문제가 발생할 수 있다. 계산된 컬럼에 인덱스를 설정하여, 이를 데이터베이스에 영구적으로 저장하는 방법이 이러한 문제의 대안으로 사용될 수 있다.(좀 더 자세한 정보는 Brian Lawton의 “뒷뜰에 숨겨진 보물단지” 기사(InstantDoc ID 42264)를 참조한다.) 계산된 컬럼에 대한 요구조건은 시간이 경과함에 따라 변경될 수 있는 것이고, 테이블 구조도 변경될 수도 있다. 테이블에 많은 컬럼이 존재하고, 해당 컬럼내역을 어플리케이션에서 사용하고 있는 환경이라면, 테이블 구조를 변경하는 것은 문제가 된다. 테이블 구조를 변경하는 대신 계산된 데이터를 가지고 있는 뷰를 생성한 다음, 해당 뷰를 실체화화여 데이터베이스에 저장할 수 있다. 계산된 컬럼에 대한 계산처리 알고리즘이 변경된 경우에는 인덱스된 뷰만 삭제한 다음, 다시 만들면 되기 때문에, 계산된 컬럼이 포함된 테이블을 수정하는 것보다는 훨씬 관리하기가 쉽다.
목록 3: 계산된 컬럼을 처리하기 위한 인덱스된 뷰
목록 3과 같이, 상세 데이터를 요약하는 실체화된 뷰를 쉽게 설정할 수 있다. 목록 3의 코드는 Orders 테이블과 Order Details 테이블로부터 총계를 집계하여 계산된 컬럼 뷰를 생성하는 역할을 한다. 쿼리가 실행될 때마다 주문에 대한 총계정보를 매번 재계산하는 것보다는, Order_Totals라는 실체화된 뷰를 생성하여 해당 뷰의 데이터로 총계정보가 저장될 수 있도록 하는 것이 더 쉽게 총계정보를 관리하는 방법이 될 수 있다. 그림 4에는 계산된 요약정보의 일부가 나타나 있다.
로컬 웹 어플리케이션 지원. 웹기반 어플리케이션의 특성상 많은 오버헤드가 발생하게 된다. 단순히 웹 브라우저에 화면을 표시하는데에도 상당한 시간이 소요된다. 웹 사용자가 데이터베이스로 데이터 요청을 보내게 되면, 성능상 데이터베이스에 또 부가적인 지연현상의 원인이 될 수 있기 때문에, 결국 웹 어플리케이션을 사용불가능 상태로 만들 수도 있다. 웹 어플리케이션을 지원해야 하는 경우라면, 데이터베이스가 빠른 응답속도를 유지할 수 있도록 튜닝작업을 수행해야 한다. 웹 데이터베이스 개발 및 설계 관련서적에서는 언제나 데이터베이스를 정규화하는 것과 테이블에 인덱스를 생성하는 것이라는, 두 가지 측면에 대해 강조한다. SQL Server 쿼리 최적화기는 가능하다면 언제나 인덱스를 사용하기 때문에, 인덱스된 뷰는 데이터 조회측면에서는 매우 탁월한 선택이 될 수 있다. 웹 브라우저로부터 요청된 쿼리에 대해 인덱스된 뷰를 생성하게 되면, 웹 어플리케이션의 응답속도를 확실하게 개선할 수 있을 것이다.
실체화된 뷰 만들기
SQL Server 2000의 모든 Edition에서 모두 인덱스된 뷰를 생성할 수 있지만, Enterprise Edition과 Developer Edition의 쿼리 최적화기에서만 뷰에 설정된 인덱스를 활용하여 쿼리계획을 수립하게 된다. (인덱스된 뷰의 제약사항에 대한 좀 더 자세한 정보는 Microsoft 기사 "SQL Server 2000의 모든 에디션에서 인덱스된 뷰를 생성가능"( http://support.microsoft.com/default.aspx?scid=kb;[LN];270054)를 참조한다. Enterprise Edition과 Developer Edition을 제외한 나머지 에디션에 포함된 쿼리 최적화기에서는 WITH(NOEXPAND) 쿼리힌트를 사용하기 전까지는 인덱스된 뷰를 포함하여 쿼리 계획을 생성하지 못한다.
실체화된 뷰를 생성하는 절차를 살펴보기 위해, SQL Server 2000 Standard Editon과 Personal Edition에서는 다음과 같은 절차를 따라하면 된다.:
1. 엔터프라이즈 관리자를 실행한다.
2. Northwind 데이터베이스를 선택한다
3. Northwind 데이터베이스를 선택 후 보기 메뉴의 작업 창을 선택한다.
4. 작업 창에서, 테이블정보 탭을 선택한 다음, 조회되는 결과를 확인한다.
5. 쿼리 분석기를 실행시키고, Northwind 데이터베이스를 사용하도록 설정한다.
6. 이번호에 제공된 예제 코드 목록 중에서 아무 것이 사용하여 인덱스된 뷰를 만든다.
7. ALT-TAB 으로 엔터프라이즈 관리자로 이동한 다음, 작업 창 화면을 재갱신한다.
생성한 인덱스 뷰가 정확한 요구사항을 충족할 수 있도록 생성되었는지와 실제 데이터베이스에 존재하는 사용자 테이블에 목록화되었는지 확인하는 절차가 필요하다. 인덱스된 뷰는 가상이 아니라 영구적으로 존재하게 되며, 데이터베이스내에 실제적인 공간을 차지하게 되며, 실제 테이블의 데이터와 인덱스된 데이터가 동일한지 체크하기 위한 동기화작업이 지속적으로 이루어질 수 있도록 반복적인 처리과정이 필요하다.
SQL Server 2000 Standard Edition의 쿼리 최적화기에서는 사용자 쿼리에 특별한 지시어(FROM절에 WITH(NOEXPAND)옵션)을 사용하지 않는 한 인덱스된 뷰를 사용할 수 없기 때문에 자원사용의 문제를 해결할 수 없다. 만약, SQL Server2000 Enterprise(또는 Developer) Edition이 아닌 경우에 인덱스 뷰를 사용하기 위해서는, 강제적으로 쿼리 최적화기가 해당 뷰를 사용하도록 해야 한다.
맨 처음 예제에서 살펴본 일반적인 뷰를 생성하는 방법에 WITH SCHEMABINDING 이라는 표현식만 추가하면, 앞부분의 세 가지 예제에서 볼 수 있는 것과 같이 인덱스된 뷰를 생성할 수 있다. 스키마 바인딩은 기존 테이블의 스키마 또는 구조를 변경할 수 없도록 잠그는 역할을 하게 되며, 원본 테이블의 구조가 변경되어 인덱스된 뷰가 실제 테이블에 근거를 두지 못하는 상황이 발생하지 않도록 통제하는 역할을 한다. 인덱스된 뷰를 제거하지 않고서는 기존 테이블의 구조를 변경할 수 없다. 테이블의 스키마를 변경해야 하는 상황이라면, 먼저, 인덱스된 뷰를 삭제한 다음, 원본 테이블의 스키마를 변경하고 다시 인덱스된 뷰를 생성해야 한다.
뷰를 실체화하기 위한 다음 작업단계는 뷰에 유일한 식별자를 가지는 클러스터된 인덱스를 생성하는 것이다. 인덱스를 생성하기 위해서는, 뷰에 유일하게 식별할 수 있는 식별자를 가지고 있어야 한다. 바로 이러한 점 때문에, 인덱스된 뷰를 만들때는 데이터에 대한 이해가 선행되어야 한다.
목록 2의 코드에서, 필자는 뷰를 생성하기 위한 쿼리에 TerritoryDescription는 유일한 식별자의 역할을 할 수 없기 때문에 TerritoryDescription이 대신 TerritoryID를 포함시켰다. 코드에서는 TerritoryID와 EmployeeID를 조합하여 유일하게 식별할 수 있는 클러스터된 인덱스를 생성하였다. EmployeeID만으로는 뷰의 결과값에서 유일한 식별자가 되지 않는다. 또한 TerritoryDescription 컬럼 자체에 중복된 값이 포함되어 있기 때문에, 후보키로서의 역할을 할 수 없어서, EmployeeID와 TerritoryDescription 컬럼을 조합한다고 하더라도 인덱스를 생성하기 위한 유일한 식별자로서의 역할을 할 수 없다.
인덱스된 뷰 관리
뷰가 실체화되었는지를 확인하기 위해서는, 생성한 인덱스된 뷰를 매개변수로 하여 sp_spaceused 명령을 실행해 보면 된다. 그림 5를 보면, 명령을 실행한 결과가 어떻게 나타나는지 알 수 있다. 뷰를 실체화한 다음, 인덱스된 뷰에 클러스터되지 않은 부가 인덱스를 추가할 수 있다. 하지만, 트랜잭션 처리를 위한 데이터베이스라면, 삽입, 변경, 삭제 작업이 발생할 때마다 인덱스된 뷰를 유지하기 위해 추가적인 오버헤드가 발생하기 때문에 인덱스의 수를 늘리는 것에 대해서 신중하게 고려해야 한다. SQL Server는 실제 원본 테이블이 변경될 때마다 자동적으로 인덱스된 뷰의 컨텐츠와 동기화하게 되며, 이 과정에서 정확한 데이터의 일관성을 보장하기 위해 CPU 시간과 물리적인 I/O를 소비하게 된다.
<그림 5> sp_spaceused 저장 프로시저 실행결과
name rows reserved data index_size unused
--------------------- -------- ---------- --------- ----------- ---------
Employee_By_Region 49 32 KB 16 KB 16 KB 0 KB
모든 뷰를 실체화할 수는 없는 것이다. 뷰에 인덱스를 생성하기 위해서는, 많은 법칙과 규정을 준수해야만 하며, 관련된 정보로는 Kalen Delaney의 2000년 5월호 기사, “인덱스된 뷰의 소개”(InstantDoc ID 8410)을 참조한다.
인덱스된 뷰도 기타 일반적인 뷰를 관리하는 방법과 동일하게 관리하게 된다. Sp_help와 sp_helptext 저장프로시저를 사용하여, 뷰의 각 컬럼의 정의와, 뷰를 생성하는데 사용된 코드를 살펴볼 수 있다. 데이터베이스에서 인덱스된 뷰를 제거하기 위해서는, DROP VIEW 명령를 사용하면 된다. 뷰를 실체화하기 위해서 설정한 클러스터된 인덱스만을 삭제하기를 바란다면, DROP INDEX 명령을 사용하면 된다. 또한 DROP INDEX 명령은 테이블에서와 마찬가지로 클러스터된 인덱스를 기반으로 추가로 만들어진 클러스터되지 않은 인덱스를 제거하기 위해서도 동일하게 사용할 수 있다. 뷰를 변경할 필요가 있다면, ALTER VIEW 명령을 사용할 수 있지만, 뷰를 변경하게 되면 모든 인덱스는 삭제된다. 그렇기 때문에, 뷰를 변경한 경우에는 모든 인덱스를 새로 만들어 주어야 한다.
좀 더 빠른 쿼리속도, 상대적으로 느린 업데이트
데이터베이스 환경에서 행해지는 모든 일에는 반드시 장단점이 공존한다. 쿼리속도를 개선하기 위해서 인덱스된 뷰를 생성한 경우를 좀 더 자세히 살펴보게 되면, 삽입, 변경, 삭제작업의 성능에 악영향을 미치게 된다는 것을 알게 된다. 그렇기 때문에 운영환경시스템과 완벽하게 분리된 별도의 개발환경에서 각각의 장단점간의 영향력을 주의깊게 계획하고 테스트해 보아야 한다. 인덱스된 뷰가 성능에 미치는 영향에 대해서는 Itzik Ben-Gan의 2002년 12월호 기사 “인덱스된 뷰의 관점”기사에서 언급된 것과 같이, 데이터비교작업에서는 약 17배, 유일성을 가진 값을 찾는 Distinct 연산의 경우는 약 23배의 성능이 향상된다.
실체화된 뷰가 가장 큰 효과를 발휘할 수 있는 환경은 주로 읽기전용 작업을 수행하며 가끔씩만 데이터 변경이 발생하는 데이터웨어하우스와 의사결정지원시스템이라고 할 수 있다. 하지만, 일부 트랜잭션 처리 환경에서도 인덱스된 뷰가 매우 유용하게 사용될 수 있다. 예를 들어, 한 테이블이 매우 대규모이고(1 GByte를 초과하는 경우), 반복적인 집계작업이나 또 다른 대용량 테이블과 조인하는 작업이 필요한 경우라면, 이러한 양쪽 테이블을 원본으로 하는 실체화된 뷰를 사용하는 것도 고려하고 테스트해 볼 필요가 있다. 반면에 매우 대량의 삽입 및 변경작업이 발생하고, 데이터베이스에 대해 클러스터된 키값을 기준으로 하지 않고, 다른 임의 레코드를 조건으로 하는 조회작업이 많은 경우에는 실체화된 뷰를 사용하는 것이 바람직하지 않다. 뷰에 설정된 인덱스를 유지보수하기 위한 오버헤드는 분명히 데이터베이스 성능을 저하시키는 원인이 된다.
실체화된뷰는 매우 신중하고 주의깊게 사전 점검을 한 이후에 사용해야 하며, 대용량 쿼리의 성능을 개선하는데 매우 도움될 수 있다. 하지만, 인덱스된 뷰가 모든 성능관련 문제의 만병통치약은 아니다. 삽입 및 변경에 대한 성능 저하의 원인이 된다는 것에 대해서 고려하지 않고, 신중한 테스트 절차 없이 인덱스된 뷰를 사용하는 것은 바람직하지 않다. 하지만, 시기적절하게 잘 사용하기만 한다면, 인덱스된 뷰를 적용하기 위해 테스트과정에서 소요된 시간과 노력을, 실제 운영환경에서 모두 다 보상받고도 남을 만큼 뛰어난 성능개선을 얻을 수 있을 것이다.
출처 : Windows&.net[2004년도 7월호]
돈만 있다면, 인덱스된 뷰를 사용하여 쿼리를 좀 더 간단하게 작성할 수 있다.
SQL Server의 차기버전인, SQL Server 2005에는 생산성을 높여 줄 수 있는 많은 기능과 확장성이 포함되어 있으며, 특히, 데이터베이스 기반 웹 어플리케이션을 개발하는 경우라면 더욱 도움이 될 것이다. ( SQL Server 2005의 전체적인 개관에 대해서는 SQL Server 메거진의 2004년 5월호를 살펴보면 된다.) 하지만, Microsoft에서는 SQL Server 2005의 최종 릴리즈 시기를 내년 상반기로 연기하였고, 많은 소프트웨어 판매점들은 적어도 최종 릴리즈이후 약 1년정도는 신규 데이터베이스 시스템으로 이행하지 않을 것이다. 결국, 현재 사용자들은 향후 일정기간동안 좀 더 SQL Server2000의 기능을 활용하게 될 것이다.
필자는 데이터 모델링 전문가와 설계 분석가로 일하고 있다. 그래서, 필자는 본능적으로 테이블 스키마를 확인하고 이를 최적화한다. 필자의 컬럼 “Solutions By Design”을 정규적으로 읽는 독자라면, 데이터를 추가하거나 관리하기 위해, 또한 데이터에 대한 일관성을 보장하기 위해서, 테이블의 정규화가 필수적이라는 사실을 강력하게 주장한다는 것에 대해 잘 알고 있을 것이다. 정규화의 장점은 정규화되어 있는 테이블에서 데이터를 조회하기 위해 여러 개의 테이블을 조인해야 한다는 불편함보다 훨씬 더 가치있는 것이다. 또한, 잘 정규화된 데이터베이스로부터 데이터를 조회하거나, 요약보고서를 작성하기 위한 대량의 데이터를 집계작업을 수행하기 위해, 네 개 또는 다섯 개의 테이블을 조인해야 하는 작업의 부가적인 오버헤드를 제거할 수 있는 방법이 있다. 이를 위해, SQL Server엔진이 쿼리가 실행되는 시점에 매번 뷰를 동적으로 재구성하지 않도록 “실체화(materialize)”된 뷰를 만들 수 있다. 즉, 뷰가 가상 테이블이 아닌 실제 물리적인 테이블이 되는 것이다.
일반적으로 뷰는 파생된 가상 테이블이다. 뷰는 사용자를 제한할 필요가 있는 중요데이터나 민감한 데이터를 숨기기 위한 접근 통제의 목적으로 사용되기도 하고, 관련된 정보를 좀 더 가치있는 정보 컨텍스트 단위로 표현하여 데이터의 가시성을 향상시키기 위한 목적으로 사용된다. SQL Server에서는 뷰에 대한 “실체화(materialize)”를 지원하는데, 이는 뷰에 유일한 클러스터된 인덱스를 생성하는 것을 의미하며, 이러한 실체화된 뷰를 “인덱스된 뷰”라고 한다. 클러스터된 인덱스와 마찬가지로, 실체화된 뷰는 실제로 사용자 데이터를 저장하게 된다.
실체화된 뷰는 데이터베이스 세계에서는 새로운 개념이 아니다. 비록, 인덱스된 뷰가 SQL Server 2000에서부터 지원된 새로운 기능이기는 하지만, ORACLE이나 DB2와 같은, 기존 다른 데이터베이스 관리 시스템에서는 이미 오래 전부터 동일한 기능을 제공해왔다. 대용량 DBMS 공급자들은 데이터웨어하우스 시스템의 성능을 향상시키기 위해 실체화된 뷰를 개발했었다. 데이터웨어하우스 시스템을 구축하기 위해서는 기술적으로 여러가지 서로 다른 데이터 원본으로부터 하나의 대용량 데이터 저장소로 데이터를 통합하는 작업이 필요하다. 데이터 저장소에는 운영 어플리케이션에서 사용할 상세 데이터가 저장되기도 하고, 의사결정지원시스템에서 사용할 요약 데이터도 저장되기도 하며, 양쪽 모두가 동시에 저장되기도 한다. 데이터웨어하우스에서, 일반적으로 데이터는 몇 가지 차원(예를 들어, 시간, 지역, 품목 등)으로 요약되게 되며, OLAP 및 의사결정지원 어플리케이션을 통해 집계작업 처리를 처리하여 데이터 저장소에 저장하게 된다. 다음에서는 데이터웨어하우스 이외의 다른 환경에서 실체화된 뷰를 유용하게 사용하는 예제에 대해서 살펴보게 된다.
왜 실체화된 뷰를 사용하는가?
실체화된 뷰가 데이터웨어하우스의 쿼리성능향상을 위해 만들어졌다면, 왜 굳이 트랜잭션 처리 데이터베이스에 실체화된 뷰를 사용하려고 하는가에 대한 의구심을 들 수 있다. 트랜잭션 데이터베이스 설계를 하는 경우라면, 마치 스포츠카 설계자와 마찬가지로, 속도와 민첩함을 중점으로 하여 설계를 진행하게 되기 때문에, 인덱스와 같은 데이터베이스 개체를 최소화하게 되고, 결국은 성능상에 문제의 원인이 된다. 트랜잭션 처리 데이터베이스의 경우, 데이터 조회의 성능을 개선하기 위해서는 인덱스가 사용되지만, 대표적인 성공사례를 기반으로 생각하여 볼 때, 인덱스는 데이터를 삽입하거나 변경할 때 별도의 오버헤드를 발생시키기 때문에 반드시 필수적으로 필요한 경우에 한하여 생성하는 것을 권장한다. 추가적으로, 실체화된 뷰는 하나 또는 그 이상의 테이블의 복사본이라고 볼 수 있기 때문에, 데이터 저장소의 공간도 실제적으로 두 배가 소요되게 된다.
실체화된 뷰는 데이터에 매우 빠르게 접근할 수 있도록 해 준다. 일반적으로, 실체화된 뷰를 사용하여 성능상의 개선사항은 실체화된 뷰를 위해서 투자되는 비용, 예를 들어, 실체화된 뷰와 실제 테이블의 데이터를 동기화하기 위해 소요되는 여분의 디스크 공간 및 프로세서의 비용을 충분히 보상하고도 남는다. 하지만, 무조건 실체화된 뷰를 사용하여 얻은 성능상의 개선효과가 실체화된 뷰를 관리하기 위해 소요되는 디스크 공간 및 프로세서의 비용보다 더 큰 것은 아니며, 이는 상황에 따라 매우 달라질 가능성이 있다. 그래서, 실체화된 뷰를 사용할 것인지 여부를 결정하기 위해 테스트를 진행할 때, 고려할 사항을 살펴보기 위해 몇가지 예제 시나리오를 살펴보고자 한다. 인덱스된 뷰를 추가하면 데이터변경작업에 오버헤드가 발생하기 때문에, 인덱스된 뷰를 적용할 수 있는 가장 좋은 대상은 거의 정적으로 유지되다가 피크시간이 아닌 시간대에 데이터에 대한 추가 및 변경이 발생하는 테이블이 될 수 있다.
운영 데이터베이스의 데이터 요약 운영 데이터베이스의 데이터를 집계하는 작업을 할 때 시스템자원이 많이 소모된다는 것은 모두가 공감할 것이다. 이러한 집계작업에는 단순한 합계, 건수, 평균을 계산하는 것 이상의 복잡한 처리가 포함된다. SQL Server의 잠금관리자는 데이터에 대한 요청간에 균형을 유지해야 하며, 집계작업이 진행하는 동안 데이터에 대한 변경작업을 지연시킬 수 있어야 한다. 또한, 집계작업을 위한 쿼리가 실행될 때마다, 해당 레코드가 데이터 캐시에 존재하지 않는 경우에는, 하드 디스크로부터 데이터를 물리적으로 스캔하여 메모리로 올리는 작업을 수행해야 한다. 집계작업에 포함되는 데이터가 많아질수록, 좀 더 많은 물리적인 I/O가 필요하게 된다. SQL Server에는 레코드에 대한 처리작업이 완료되자마자 즉시 해당 데이터 페이지에 대한 잠금을 해제하는 것과 같은, 데이터요청에 대한 지연이 최소화될 수 있도록 하기 위한 많은 기술을 사용하고 있다. 하지만, 특히, 이미 시스템에 막대한 작업부하가 발생한 상태에서, 집계작업을 수행하는 쿼리를 실행하게 되면, 전체적인 성능저하의 원인이 될 수 있다는 것만은 확실하다.
목록 1에는 선적된 주문건에 대한 정보가 저장되어 있는, Northwind 데이터베이스의 Orders 테이블에 실체화된 요약 뷰를 생성하는 예제가 나타나 있다. 우편번호를 기준으로 주문에 대한 요약 보고서를 생성하는 것은 판매동향을 파악하기 위해 매우 유용한 정보를 제공해 줄 수 있다. 그림 1에는 목록 1의 코드를 실행시킨 결과집합의 일부가 나타나 있다. 이 요약보고서를 통해 Northwind Trader 사는 어느 우편번호 지역으로 대부분의 제품이 배송되었는지에 대해서 쉽게 분석할 수 있을 것이다.
목록 1: 요약보고서용 인덱스된 뷰 생성

<그림 1> 목록 1의 코드 실행결과
다중테이블 조인의 제거. 운영 데이터베이스환경에서는, 정보를 얻기 위해 많은 테이블을 조인해야 하는 상황이 종종 발생하게 된다. 예를 들어, Northwind 데이터베이스에서 지역별 영업사원보고서를 만들기 위해서는 네 개의 테이블을 조인해야 한다. 특정 지역에 대한 사원명부를 데이터베이스에서 쿼리하거나, 특정 지역에 대한 판매권역별 영업사원 정보를 조회하는 작업은 그리 재미있는 작업은 아니지만, 꼭 필요한 작업이다. 그림 2에 나타나 있는 ERD에서 확인할 수 있듯이, Northwind 데이터베이스와 같이 매우 잘 정규화된 데이터베이스에서는, SQL Server가 필요한 데이터를 반환하기 위해 여러 테이블간의 조인 연산을 하는 과정에서 쿼리가 지연되는 문제를, 실체화된 뷰를 사용함으로써 해결할 수 있다. 목록 2의 코드에는 네 개의 테이블을 조인한 결과에 대해 실체화된 뷰를 생성하는 예제가 나타나 있다. 그림 3에는 목록 2의 코드를 실행한 결과의 일부분이 나타나 있다.

그림 2 Northwind 데이터베이스 ERD
목록 2: 네 개의 테이블을 조인하는 인덱스된 뷰

<그림 3> 목록2의 코드 실행결과
계산된 컬럼을 분리하여 관리. 잘 정규화된 데이터베이스에서 준수하고 있는 원칙 중의 하나는 사용자 데이터로부터 파생된 계산된 데이터는 별도의 테이블로 저장하고 있다는 것이다. 계산된 데이터는 시스템에 매일매일 발생하는 데이터 처리건에서 집계된 데이터라 할 수 있으며, 2차적인 데이터 처리절차라고 할 수 있다. 만약, 데이터베이스에 누계정보나 합계정보를 계산하고자 하는 경우, 지속적인 재계산 작업으로 인한 오버헤드가 발생하기 때문에, 원본 데이터 테이블에 합계정보의 계산결과를 저장하지는 않을 것이다.
물론, 테이블에 계산된 컬럼을 생성할 수 있다. 하지만, 계산된 컬럼은 가상 컬럼이다. 일반적인 뷰와 같이, 계산된 결과값은 저장되지 않으며, 쿼리에 의해 해당 컬럼의 값이 요청될 때마다 SQL Server는 동적으로 해당 컬럼값을 계산하게 된다. 테이블에 행이 많지 않다면, 동적 재계산작업이 문제가 되지 않는다. 하지만, 테이블의 1GByte 이상의 대용량인 경우, 매우 심각한 성능상의 문제가 발생할 수 있다. 계산된 컬럼에 인덱스를 설정하여, 이를 데이터베이스에 영구적으로 저장하는 방법이 이러한 문제의 대안으로 사용될 수 있다.(좀 더 자세한 정보는 Brian Lawton의 “뒷뜰에 숨겨진 보물단지” 기사(InstantDoc ID 42264)를 참조한다.) 계산된 컬럼에 대한 요구조건은 시간이 경과함에 따라 변경될 수 있는 것이고, 테이블 구조도 변경될 수도 있다. 테이블에 많은 컬럼이 존재하고, 해당 컬럼내역을 어플리케이션에서 사용하고 있는 환경이라면, 테이블 구조를 변경하는 것은 문제가 된다. 테이블 구조를 변경하는 대신 계산된 데이터를 가지고 있는 뷰를 생성한 다음, 해당 뷰를 실체화화여 데이터베이스에 저장할 수 있다. 계산된 컬럼에 대한 계산처리 알고리즘이 변경된 경우에는 인덱스된 뷰만 삭제한 다음, 다시 만들면 되기 때문에, 계산된 컬럼이 포함된 테이블을 수정하는 것보다는 훨씬 관리하기가 쉽다.
목록 3: 계산된 컬럼을 처리하기 위한 인덱스된 뷰
목록 3과 같이, 상세 데이터를 요약하는 실체화된 뷰를 쉽게 설정할 수 있다. 목록 3의 코드는 Orders 테이블과 Order Details 테이블로부터 총계를 집계하여 계산된 컬럼 뷰를 생성하는 역할을 한다. 쿼리가 실행될 때마다 주문에 대한 총계정보를 매번 재계산하는 것보다는, Order_Totals라는 실체화된 뷰를 생성하여 해당 뷰의 데이터로 총계정보가 저장될 수 있도록 하는 것이 더 쉽게 총계정보를 관리하는 방법이 될 수 있다. 그림 4에는 계산된 요약정보의 일부가 나타나 있다.

그림 4 Order_Total 뷰 쿼리 결과
로컬 웹 어플리케이션 지원. 웹기반 어플리케이션의 특성상 많은 오버헤드가 발생하게 된다. 단순히 웹 브라우저에 화면을 표시하는데에도 상당한 시간이 소요된다. 웹 사용자가 데이터베이스로 데이터 요청을 보내게 되면, 성능상 데이터베이스에 또 부가적인 지연현상의 원인이 될 수 있기 때문에, 결국 웹 어플리케이션을 사용불가능 상태로 만들 수도 있다. 웹 어플리케이션을 지원해야 하는 경우라면, 데이터베이스가 빠른 응답속도를 유지할 수 있도록 튜닝작업을 수행해야 한다. 웹 데이터베이스 개발 및 설계 관련서적에서는 언제나 데이터베이스를 정규화하는 것과 테이블에 인덱스를 생성하는 것이라는, 두 가지 측면에 대해 강조한다. SQL Server 쿼리 최적화기는 가능하다면 언제나 인덱스를 사용하기 때문에, 인덱스된 뷰는 데이터 조회측면에서는 매우 탁월한 선택이 될 수 있다. 웹 브라우저로부터 요청된 쿼리에 대해 인덱스된 뷰를 생성하게 되면, 웹 어플리케이션의 응답속도를 확실하게 개선할 수 있을 것이다.
실체화된 뷰 만들기
SQL Server 2000의 모든 Edition에서 모두 인덱스된 뷰를 생성할 수 있지만, Enterprise Edition과 Developer Edition의 쿼리 최적화기에서만 뷰에 설정된 인덱스를 활용하여 쿼리계획을 수립하게 된다. (인덱스된 뷰의 제약사항에 대한 좀 더 자세한 정보는 Microsoft 기사 "SQL Server 2000의 모든 에디션에서 인덱스된 뷰를 생성가능"( http://support.microsoft.com/default.aspx?scid=kb;[LN];270054)를 참조한다. Enterprise Edition과 Developer Edition을 제외한 나머지 에디션에 포함된 쿼리 최적화기에서는 WITH(NOEXPAND) 쿼리힌트를 사용하기 전까지는 인덱스된 뷰를 포함하여 쿼리 계획을 생성하지 못한다.
실체화된 뷰를 생성하는 절차를 살펴보기 위해, SQL Server 2000 Standard Editon과 Personal Edition에서는 다음과 같은 절차를 따라하면 된다.:
1. 엔터프라이즈 관리자를 실행한다.
2. Northwind 데이터베이스를 선택한다
3. Northwind 데이터베이스를 선택 후 보기 메뉴의 작업 창을 선택한다.
4. 작업 창에서, 테이블정보 탭을 선택한 다음, 조회되는 결과를 확인한다.
5. 쿼리 분석기를 실행시키고, Northwind 데이터베이스를 사용하도록 설정한다.
6. 이번호에 제공된 예제 코드 목록 중에서 아무 것이 사용하여 인덱스된 뷰를 만든다.
7. ALT-TAB 으로 엔터프라이즈 관리자로 이동한 다음, 작업 창 화면을 재갱신한다.
생성한 인덱스 뷰가 정확한 요구사항을 충족할 수 있도록 생성되었는지와 실제 데이터베이스에 존재하는 사용자 테이블에 목록화되었는지 확인하는 절차가 필요하다. 인덱스된 뷰는 가상이 아니라 영구적으로 존재하게 되며, 데이터베이스내에 실제적인 공간을 차지하게 되며, 실제 테이블의 데이터와 인덱스된 데이터가 동일한지 체크하기 위한 동기화작업이 지속적으로 이루어질 수 있도록 반복적인 처리과정이 필요하다.
SQL Server 2000 Standard Edition의 쿼리 최적화기에서는 사용자 쿼리에 특별한 지시어(FROM절에 WITH(NOEXPAND)옵션)을 사용하지 않는 한 인덱스된 뷰를 사용할 수 없기 때문에 자원사용의 문제를 해결할 수 없다. 만약, SQL Server2000 Enterprise(또는 Developer) Edition이 아닌 경우에 인덱스 뷰를 사용하기 위해서는, 강제적으로 쿼리 최적화기가 해당 뷰를 사용하도록 해야 한다.
맨 처음 예제에서 살펴본 일반적인 뷰를 생성하는 방법에 WITH SCHEMABINDING 이라는 표현식만 추가하면, 앞부분의 세 가지 예제에서 볼 수 있는 것과 같이 인덱스된 뷰를 생성할 수 있다. 스키마 바인딩은 기존 테이블의 스키마 또는 구조를 변경할 수 없도록 잠그는 역할을 하게 되며, 원본 테이블의 구조가 변경되어 인덱스된 뷰가 실제 테이블에 근거를 두지 못하는 상황이 발생하지 않도록 통제하는 역할을 한다. 인덱스된 뷰를 제거하지 않고서는 기존 테이블의 구조를 변경할 수 없다. 테이블의 스키마를 변경해야 하는 상황이라면, 먼저, 인덱스된 뷰를 삭제한 다음, 원본 테이블의 스키마를 변경하고 다시 인덱스된 뷰를 생성해야 한다.
뷰를 실체화하기 위한 다음 작업단계는 뷰에 유일한 식별자를 가지는 클러스터된 인덱스를 생성하는 것이다. 인덱스를 생성하기 위해서는, 뷰에 유일하게 식별할 수 있는 식별자를 가지고 있어야 한다. 바로 이러한 점 때문에, 인덱스된 뷰를 만들때는 데이터에 대한 이해가 선행되어야 한다.
목록 2의 코드에서, 필자는 뷰를 생성하기 위한 쿼리에 TerritoryDescription는 유일한 식별자의 역할을 할 수 없기 때문에 TerritoryDescription이 대신 TerritoryID를 포함시켰다. 코드에서는 TerritoryID와 EmployeeID를 조합하여 유일하게 식별할 수 있는 클러스터된 인덱스를 생성하였다. EmployeeID만으로는 뷰의 결과값에서 유일한 식별자가 되지 않는다. 또한 TerritoryDescription 컬럼 자체에 중복된 값이 포함되어 있기 때문에, 후보키로서의 역할을 할 수 없어서, EmployeeID와 TerritoryDescription 컬럼을 조합한다고 하더라도 인덱스를 생성하기 위한 유일한 식별자로서의 역할을 할 수 없다.
인덱스된 뷰 관리
뷰가 실체화되었는지를 확인하기 위해서는, 생성한 인덱스된 뷰를 매개변수로 하여 sp_spaceused 명령을 실행해 보면 된다. 그림 5를 보면, 명령을 실행한 결과가 어떻게 나타나는지 알 수 있다. 뷰를 실체화한 다음, 인덱스된 뷰에 클러스터되지 않은 부가 인덱스를 추가할 수 있다. 하지만, 트랜잭션 처리를 위한 데이터베이스라면, 삽입, 변경, 삭제 작업이 발생할 때마다 인덱스된 뷰를 유지하기 위해 추가적인 오버헤드가 발생하기 때문에 인덱스의 수를 늘리는 것에 대해서 신중하게 고려해야 한다. SQL Server는 실제 원본 테이블이 변경될 때마다 자동적으로 인덱스된 뷰의 컨텐츠와 동기화하게 되며, 이 과정에서 정확한 데이터의 일관성을 보장하기 위해 CPU 시간과 물리적인 I/O를 소비하게 된다.
<그림 5> sp_spaceused 저장 프로시저 실행결과
name rows reserved data index_size unused
--------------------- -------- ---------- --------- ----------- ---------
Employee_By_Region 49 32 KB 16 KB 16 KB 0 KB
모든 뷰를 실체화할 수는 없는 것이다. 뷰에 인덱스를 생성하기 위해서는, 많은 법칙과 규정을 준수해야만 하며, 관련된 정보로는 Kalen Delaney의 2000년 5월호 기사, “인덱스된 뷰의 소개”(InstantDoc ID 8410)을 참조한다.
인덱스된 뷰도 기타 일반적인 뷰를 관리하는 방법과 동일하게 관리하게 된다. Sp_help와 sp_helptext 저장프로시저를 사용하여, 뷰의 각 컬럼의 정의와, 뷰를 생성하는데 사용된 코드를 살펴볼 수 있다. 데이터베이스에서 인덱스된 뷰를 제거하기 위해서는, DROP VIEW 명령를 사용하면 된다. 뷰를 실체화하기 위해서 설정한 클러스터된 인덱스만을 삭제하기를 바란다면, DROP INDEX 명령을 사용하면 된다. 또한 DROP INDEX 명령은 테이블에서와 마찬가지로 클러스터된 인덱스를 기반으로 추가로 만들어진 클러스터되지 않은 인덱스를 제거하기 위해서도 동일하게 사용할 수 있다. 뷰를 변경할 필요가 있다면, ALTER VIEW 명령을 사용할 수 있지만, 뷰를 변경하게 되면 모든 인덱스는 삭제된다. 그렇기 때문에, 뷰를 변경한 경우에는 모든 인덱스를 새로 만들어 주어야 한다.
좀 더 빠른 쿼리속도, 상대적으로 느린 업데이트
데이터베이스 환경에서 행해지는 모든 일에는 반드시 장단점이 공존한다. 쿼리속도를 개선하기 위해서 인덱스된 뷰를 생성한 경우를 좀 더 자세히 살펴보게 되면, 삽입, 변경, 삭제작업의 성능에 악영향을 미치게 된다는 것을 알게 된다. 그렇기 때문에 운영환경시스템과 완벽하게 분리된 별도의 개발환경에서 각각의 장단점간의 영향력을 주의깊게 계획하고 테스트해 보아야 한다. 인덱스된 뷰가 성능에 미치는 영향에 대해서는 Itzik Ben-Gan의 2002년 12월호 기사 “인덱스된 뷰의 관점”기사에서 언급된 것과 같이, 데이터비교작업에서는 약 17배, 유일성을 가진 값을 찾는 Distinct 연산의 경우는 약 23배의 성능이 향상된다.
실체화된 뷰가 가장 큰 효과를 발휘할 수 있는 환경은 주로 읽기전용 작업을 수행하며 가끔씩만 데이터 변경이 발생하는 데이터웨어하우스와 의사결정지원시스템이라고 할 수 있다. 하지만, 일부 트랜잭션 처리 환경에서도 인덱스된 뷰가 매우 유용하게 사용될 수 있다. 예를 들어, 한 테이블이 매우 대규모이고(1 GByte를 초과하는 경우), 반복적인 집계작업이나 또 다른 대용량 테이블과 조인하는 작업이 필요한 경우라면, 이러한 양쪽 테이블을 원본으로 하는 실체화된 뷰를 사용하는 것도 고려하고 테스트해 볼 필요가 있다. 반면에 매우 대량의 삽입 및 변경작업이 발생하고, 데이터베이스에 대해 클러스터된 키값을 기준으로 하지 않고, 다른 임의 레코드를 조건으로 하는 조회작업이 많은 경우에는 실체화된 뷰를 사용하는 것이 바람직하지 않다. 뷰에 설정된 인덱스를 유지보수하기 위한 오버헤드는 분명히 데이터베이스 성능을 저하시키는 원인이 된다.
실체화된뷰는 매우 신중하고 주의깊게 사전 점검을 한 이후에 사용해야 하며, 대용량 쿼리의 성능을 개선하는데 매우 도움될 수 있다. 하지만, 인덱스된 뷰가 모든 성능관련 문제의 만병통치약은 아니다. 삽입 및 변경에 대한 성능 저하의 원인이 된다는 것에 대해서 고려하지 않고, 신중한 테스트 절차 없이 인덱스된 뷰를 사용하는 것은 바람직하지 않다. 하지만, 시기적절하게 잘 사용하기만 한다면, 인덱스된 뷰를 적용하기 위해 테스트과정에서 소요된 시간과 노력을, 실제 운영환경에서 모두 다 보상받고도 남을 만큼 뛰어난 성능개선을 얻을 수 있을 것이다.
출처 : Windows&.net[2004년도 7월호]
"MSSQL" 카테고리의 다른 글
- 과도한 동기화 (0)2007/05/21
- 검색 제한자 깊이보기 (0)2007/05/21
- 뷰를 실체화하기 (0)2007/05/21
- 지금 SQL 서버에서는 어떤 문제들이 벌어지고 있을까? (1)2007/05/21
- SQL Server 2000에서 varchar와 char 데이터 타입 (0)2007/05/21

수안이의 컴퓨터 연구실



Leave your greetings.