출처 : http://mobile.moba.co.kr/database/lecture/sqlserver/queryproc.htm

위 주소를 클릭하여 원본으로 보시면 이미지와 함께 아래 내용보다 정리된 내용으로 보실 수 있습니다. ㅋㅋ


--------------------------------------------------------------------------------
Microsoft SQL Server 7.0 쿼리 프로세서
--------------------------------------------------------------------------------




Contents


소개
쿼리 최적화


쿼리 프로세서란?
  
다중 단계 최적화


쿼리 옵티마이저 종류
  
자동 파라미터


  
구문 기반 쿼리 옵티마이저
  
삼단논법


  
비용 기반 쿼리 옵티마이저
  
중첩 쿼리

Microsoft SQL Server 7.0의 목표
  
GROUP BY 절 이동


제품 목표
  
파티셔닝 뷰


  
사용의 용이성
  
스타 쿼리


  
확장성 및 신뢰성
  
  
순서 쌍(cartesian product) 및 복합 인덱스


  
데이터 웨어하우징
  
  
세미 조인 감소 (Semi-join Reduction) 및 인덱스 교집합


  
리더십 및 혁신
  
  
결합된 기술


쿼리 프로세서 목표
  
최적화된 업데이트


  
쿼리 옵티마이저에 대한 더 많은 선택
분산 쿼리


  
향상된 쿼리 실행
  
이기종 쿼리


  
쿼리의 병렬 실행
  
통과(Pass-through) 쿼리


  
데이터 웨어하우스 쿼리에 대한 최적화
쿼리 작업


  
데이터베이스 관리자 개입의 최소화
  
쿼리 분석기(Query Analyzer)


  
쿼리 문제 진단 및 수정에 있어서의 향상된 도구
  
쿼리 가버너(Query Governor)

쿼리 실행
  
프로파일러 (SQL Server Profiler)


디스크 I/O
  
인덱스 튜닝 마법사


  
순차적 I/O와 임의 I/O
  
자동 통계 작성 및 자동 갱신


  
대형 I/O
결론


  
미리 읽기 스캔
추가 정보 찾기


  
프리패치 힌트
  
추가 참고 사항


정렬 향상
  


병합 조인, 해쉬 조인 및 해쉬 팀
  


  
병합 조인
  


  
해쉬 조인
  


  
해쉬 팀
  


인덱스 교집합
  


인덱스 조인
  


병렬 계획
  


  
병렬성에 영향을 주는 요인
  


기타 병렬 작업
  




소개

Microsoft® SQL Server™ 버전 7.0은 Microsoft SQL Server 버전 6.5로 다진 튼튼한 기초 위에 세워졌으며, Microsoft 데이터베이스 제품의 특징을 규정합니다. 고객들의 필요와 요구로 인해 SQL Server 7.0에서는 중대한 제품 혁신을 이루었습니다. 운영 체제의 Microsoft Windows® 제품군에 대한 최상의 관계형 데이터베이스 관리 시스템(RDBMS)인 SQL Server는 회사 고객과 개별 소프트웨어 협력업체(ISVs)에게 최상의 선택이 될 것입니다.

이 문서는 데이터베이스 서버에서 SQL 구문을 받아들이고, 그 구문의 실행 방법을 결정하고, 선택된 계획을 실행하는 부분인 SQL Server 쿼리 프로세서의 혁신과 향상된 점을 설명합니다. SQL Server 7.0은 다른 상업적으로 사용가능한 RDBMS 제품과 비교할 때 상당한 혁신을 가져왔습니다.

쿼리 프로세서의 역할, 쿼리 프로세서 종류 및 쿼리 과정의 구성 요소를 간단하게 설명한 소개 후 다음 항목을 논의할 것입니다.

  ◎ Microsoft SQL Server 7.0의 목표
  ◎ 쿼리 실행
  ◎ 쿼리 최적화
  ◎ 분산 쿼리
  ◎ 쿼리 작업

쿼리 프로세서란?

관계형 데이터베이스는 많은 부분으로 이루어져 있지만, 스토리지 엔진과 쿼리 프로세서가 가장 핵심적인 두 구성 요소입니다. 스토리지 엔진은 디스크에 데이터를 쓰고 디스크로부터 데이터를 읽으며, 로그 파일을 기록하고 동시성을 제어하고 관리합니다.

쿼리 프로세서는 SQL 구문을 받아들여, 이 구분을 실행하는 방법을 결정하고 선택된 계획을 실행합니다. 사용자나 프로그램은 쿼리 프로세서와 상호 작용하고, 쿼리 프로세서는 스토리지 엔진과 상호 작용합니다. 쿼리 프로세서로 인하여 실행의 세부 과정에는 사용자가 개입할 필요가 없습니다. 사용자는 결과를 지정하기만 하면 되고 쿼리 프로세서는 이 결과를 얻는 방법을 결정합니다.

쿼리 단계에는 쿼리 최적화와 쿼리 실행 등 두 가지 주요한 단계가 있습니다.

쿼리 최적화는 가장 빠른 실행 계획을 선택하는 과정입니다. 최적화 단계에서 쿼리 프로세서는 다음을 선택합니다.

  ◎ 사용할 인덱스(있는 경우)
  ◎ 조인이 실행되는 순서
  ◎ WHERE 절과 같은 제약이 적용되는 순서
  ◎ 통계에서 나온 비용 정보를 기본으로 하여 최상의 성능을 이끌 알고리즘

쿼리 실행은 쿼리 최적화 중에 실행되는 과정입니다. 또한 쿼리 실행 구성 요소로 쿼리 옵티마이저에 사용할 수 있는 기술을 결정합니다.

예를 들어, SQL Server는 옵티마이저에서 사용할 수 있는 해쉬 조인 알고리즘과 병합 조인 알고리즘을 모두 구현합니다.

쿼리 옵티마이저는 관계형 데이터베이스 시스템의 중추입니다. 대부분의 작업을 수동으로 수행할 수 있지만, 쿼리 프로세서로 관계형 데이터베이스를 현명하고 효율적으로 작동하게 할 수 있습니다.

두 건축 회사를 유추하여 상상해 보기로 합시다. 이 두 회사는 집을 짓는 작업을 해야 합니다. 이 집은 일정한 규모에 일정한 개수의 창, 침실, 화장실, 부엌 등이 있어야 합니다. 첫 번째 회사는 계획부터 세웁니다. 병렬로 처리할 수 있으며 이전 단계에 종속되는 단계를 지정함으로써 필요한 단계의 순서를 결정하고, 각 작업에 최고의 숙련자들을 엄선합니다. 두 번째 건축 회사는 아무런 계획 없이, 그냥 가까운 도구를 골라들고 집을 짓기 시작합니다.
작업이 단순하지 않는 한 미리 계획을 세워둔 회사가 먼저 집을 짓게 됩니다. (집 짓는 작업은 보통 간단하지 않습니다.) 이와 같은 이유로, 정교한 쿼리 옵티마이저가 있는 관계형 데이터베이스가 간단한 쿼리 옵티마이저가 있는 관계형 데이터베이스보다 질의를 더 빨리 수행합니다. 특히 복잡한 질의는 더 빨리 수행합니다.

사용가능한 도구 유형으로 작업을 얼마나 빠르게 수행할 수 있는지를 알 수 있으며, 여러 면에서는 어떠한 종류의 문제에 부딛힐 수 있는지 알 수 있습니다. 예를 들어, 덤프 트럭은 집을 지을 때는 적합하지만 정원을 청소할 때는 부적합합니다. 마찬가지로, 관계형 데이터베이스는 정교한 쿼리 옵티마이저와, 쿼리 실행에 사용할 수 있는 올바른 도구가 있어야 하며 작업에 적절한 도구를 선택해야 합니다.

쿼리 옵티마이저 종류

관계형 데이터베이스에는 구문 기반 쿼리 옵티마이저와 비용 기반 쿼리 옵티마이저 등 두 종류의 질의 옵티마이저가 있습니다.

구문 기반 쿼리 옵티마이저

구문 기반 쿼리 옵티마이저는 SQL 쿼리에 대한 답을 구하는 절차적 계획을 작성하지만, 선정된 특정 계획은 쿼리의 정확한 구문과 쿼리 내의 절(cluase) 순서에 의존합니다. 구문 기반 쿼리 옵티마이저는 데이터베이스의 레코드 수나 구성 내용이 시간에 따라 변경되는지에 상관없이 매번 동일한 계획을 실행합니다. 비용 기반 쿼리 옵티마이저와는 달리 데이터베이스에 대한 통계를 살펴보거나 관리하지 않습니다.

비용 기반 쿼리 옵티마이저

비용 기반 쿼리 옵티마이저는 SQL 쿼리에 답하는 대체 질문 중에 선택합니다. 이 때 특정 계획을 실행하기 위한 비용 측정치(I/O 작업의 수, CPU 사용 시간(초 단위) 등)를 기본으로 합니다. 이 옵티마이저는 테이블이나 인덱스 수와 컴포지션에 대한 통계를 유지하여 이러한 비용을 측정합니다. 구문 기반 쿼리 옵티마이저와는 달리 쿼리의 정확한 구문이나 쿼리 내의 절 수에 의존하지 않습니다.

SQL Server 6.5와 SQL Server 7.0은 모두 비용 기반 쿼리 옵티마이저를 구현합니다. SQL Server 7.0에서는 쿼리 옵티마이저와 쿼리 실행 엔진의 정교함이 상당히 향상되었습니다.

Microsoft SQL Server 7.0의 목표

다음은 Microsoft SQL Server 7.0의 포괄적인 목표와 쿼리 프로세서의 특정 목표입니다.

제품 목표

제품 목표는 사용의 용이성, 확장성, 신뢰성, 데이터 웨어하우징에 대한 포괄적인 지원 등입니다.

사용의 용이성

고객들은 업무 문제에 대한 솔루션을 찾고 있습니다. 많은 데이터베이스 솔루션은 비용과 복잡성만 추가합니다. Microsoft사의 전략은 SQL Server가 업무 애플리케이션을 구축하고, 관리하고 배치하기 위한 최상의 데이터베이스가 되도록 하는 것입니다. 즉, 개발자들에게 빠르고 간단한 프로그래밍 모델을 제공하고, 표준 작업에는 데이터베이스 관리 과정을 없애고, 보다 복잡한 작업에 정교한 도구를 제공한다는 것입니다.

확장성 및 신뢰성

고객들은 해당 데이터베이스에 대한 애플리케이션 형태 및 배치와 관리에 필요한 교육의 형태로 데이터베이스 관리 시스템에 투자를 합니다. 이러한 투자는 보호되어야 합니다. 사업이 성장함에 따라 데이터, 업무 및 사용자를 처리할 수 있도록 데이터베이스도 커져야 합니다. 고객들은 또한 데이터베이스 애플리케이션을 랩톱 및 지사까지 확장할 때 투자를 보호하기 원합니다. 이러한 요구를 만족시키기 위해 Microsoft에서는 Windows 95 또는 98 운영 체제를 실행하는 이동식 랩톱 컴퓨터에서 Windows NT® Server 운영 체제의 엔터프라이즈 판을 실행하는 테라바이트 규모의 다중프로세서 클러스터까지 단일 데이터베이스 엔진을 제공해 줍니다. 이러한 시스템은 모두 중요한 임무의 업무 시스템에서 요구하는 보안과 신뢰성을 유지해 줍니다.

데이터 웨어하우징

업무 처리 시스템은 회사 데이터베이스 하부구조의 핵심 구성 요소이며, SQL Server 7.0은 SQL Server 6.0과 SQL Server 6.5에서 확고하게 구축한 성능과 가격 대비 성능 분야의 선두를 계속 지켜나가고 있습니다. SQL Server의 목표는 더 많은 사용자들이 기술을 사용할 수 있도록 하면서 데이터 웨어하우징의 비용과 복잡성을 줄이는 것입니다. SQL Server 7.0은 병렬 쿼리 처리, Plato, OLAP(통합된 온라인 분석 처리) 서버, DTS(Data Transformation Services), Microsoft Repository; Visual Studio® 개발 시스템 및 통합 복제 등 데이터 웨어하우징에 대한 새로운 기능을 많이 도입하고 있습니다. 또 쿼리 프로세서는 복잡한 쿼리와 큰 데이터베이스를 처리할 수 있도록 향상되었습니다.

리더십 및 혁신

혁신적인 기능으로 인해 SQL Server 7.0은 전자 상거래, 이동식 컴퓨팅, 지사 자동화, 업무선(line-of-business) 애플리케이션, 데이터 웨어하우징 등 급속히 성장하는 데이터베이스 산업의 여러 애플리케이션 범주에서 선두로서 자리매김을 하고 있습니다.

쿼리 프로세서 목표

SQL Server의 이전 버전은 작은 쿼리와 OLTP(온라인 업무 처리)에서 나타나는 레코드별, 인덱스별 탐색에 있어서 뛰어난 성능을 가지고 있습니다. SQL Server 7.0의 목표는 의사 결정 지원, 대규모 쿼리, 복잡한 쿼리, 데이터 웨어하우징 및 OLAP에 있어서의 쿼리 프로세서를 향상시키는 것이었습니다. 이런 것들이 특정 목표들이었습니다.

쿼리 옵티마이저에 대한 더 많은 선택

SQL Server의 이전 버전에는 제한된 방법으로만 쿼리를 최적화할 수 있었습니다. 예를 들어, SQL Server 6.5에는 중첩된 루프 조인을 수행할 수 있는 방법이 한 가지 밖에 없었습니다. SQL Server 7.0은 해쉬 조인과 병합 조인을 추가하였는데, 이로 인해 옵티마이저는 선택할 수 있는 옵션이 더 많아지고, 또한 이들은 많은 대규모 쿼리에 대한 정선된 알고리즘입니다.

향상된 쿼리 실행

두 번째 목표는 일단 선택을 했으면 계획 실행을 향상시키는 것이었습니다. 더 빠른 검색, 향상된 정렬 및 큰 메모리는 모두 잠재적으로 성능을 향상시키는 요인입니다.

쿼리의 병렬 실행

SMP(Symmetric multiprocessing)와 디스크 스트라잎 세트는 점점 보편화 되어가고 있습니다. SQL Server 6.5는 병렬 I/O와 내부 쿼리 병렬성(다른 프로세서에 다른 쿼리 할당)를 구현하지만, 단일 쿼리의 다른 부분을 병렬로 수행할 수 없습니다. SQL Server 7.0은 단일 쿼리를 여러 개의 하부 작업으로 쪼개어 병렬 실행을 하기 위해 다중 프로세서를 통해 배포합니다.

데이터 웨어하우스 쿼리에 최적화

스타 스키마와 스타 쿼리는 데이터 웨어하우징 애플리케이션에 있어서 일반적입니다. 스타 쿼리는 fact table이라는 대규모 집중 테이블을 dimension table이라는 여러 개의 더 작은 테이블로 조인합니다. SQL Server 7.0은 이러한 쿼리들을 자동으로 인식하여 여러 종류의 스타 조인 계획 중에 비용 기반 선택을 합니다.

데이터베이스 관리자에 의한 최소한의 개입

현재 데이터베이스 관리자가 아주 부족하고 인건비도 아주 비싼 편입니다. 표준 작업에 있어서 데이터베이스 관리자의 개입을 최소화한다면, 데이터베이스 관리자가 복잡한 작업에 시간을 사용하도록 할 수 있습니다.

쿼리 문제 진단 및 수정을 위한 향상된 도구

SQL Server 7.0에 있는 Profiler, Query Analyzer, Index Tuning Wizard와 같은 도구를 사용하면 쿼리 문제를 규명하고 진단, 수정할 수 있습니다. 이러한 도구로 데이터베이스 관리자는 문제의 핵심을 정확하게 파악할 수 있습니다. 많은 경우 이런 도구들에는 수정 방법도 제안합니다.

쿼리 실행

쿼리 실행은 쿼리 최적화 중에 선택한 계획을 실행하는 과정입니다. 목표는 계획을 빠르게 수행하는 것입니다. 즉, 사용자에게 아주 적은 시간에 답을 제공해 주기 위한 것입니다.(사용자가 프로그램을 직접 실행하는 경우도 많습니다.) 이것은 최소한의 리소스(CPU, I/O, 메모리)로 계획을 수행하는 것과는 다릅니다. 예를 들어, 병렬 쿼리는 거의 항상 비병렬 쿼리보다 더 많은 리소스를 사용하지만, 사용자에게 더 빨리 결과를 보여주므로 더 바람직합니다.

구현된 쿼리 세트 실행 기법은 쿼리 옵티마이저가 사용할 수 있는 선택 세트를 결정해 줍니다. 이 문서는 쿼리 옵티마이저가 활용하는 기법을 완전히 이해할 수 있도록 쿼리 최적화에 앞서 쿼리 실행에 대해 설명합니다.

디스크 I/O

효율적인 쿼리 과정의 토대는 디스크와 메모리 사이의 효율적인 데이터 전송입니다. SQL Server 7.0은 디스크 I/O에 있어서의 많은 향상된 기능을 통합하고 있습니다.

순차적 I/O와 임의 I/O

I/O 작업(디스크로부터 데이터 읽기)은 컴퓨터 시스템에서 비용이 가장 많이 드는 작업 중의 하나입니다. 디스크에 저장되어 있는 순서대로 데이터를 읽는 순차적 I/O와 디스크의 특정 위치에서 다른 위치로 이동하여 무작위로 데이터를 읽는 임의 I/O 등 두 종류의 I/O 작업이 있습니다. 특히 임의 I/O는 많은 용량의 데이터를 읽을 때 순차적 I/O보다 더 많은 비용이 듭니다.

Microsoft SQL Server 7.0은 임의 I/O를 최소화하는 디스크상의 구조를 관리하고, 클러스터 인덱스가 없는, 즉 데이터 행이 특정 순서대로 저장되지 않는 테이블인 대규모 heap table의 빠른 검색을 허용합니다. 이것은 의사 결정 지원 쿼리를 위한 중요한 기능입니다. 이러한 디스크 순서에 의한 스캔은 인덱스의 정렬 순서가 순차적 처리 단계에서 필요하지 않은 경우, 클러스터 인덱스나 넌 클러스터 인덱스에도 사용할 수 있습니다.

이전 버전의 SQL Server는 테이블에 속한 데이터 페이지가 다음 페이지로 이동하는 포인터를 가지고 있는 페이지 체인을 사용하였습니다. 이러한 결과로 랜덤 I/O가 생기고, 서버에서 페이지를 읽기 전에는 다음 페이지의 위치를 가지지 않기 때문에, 미리 읽기(read ahead)를 할 수 없게 됩니다.

SQL Server 7.0은 다른 접근법을 취합니다. IAM(Index Allocation Map)은 테이블이나 인덱스에서 사용하는 페이지를 매핑합니다. IAM은 디스크 순서에서 특정 테이블에 대한 데이터 페이지의 비트맵입니다. 모든 페이지를 읽기 위해 서버는 비트맵을 스캔하고, 어떤 순서에서 어떠한 페이지를 읽어야 하는지 결정합니다. 그런 다음 순차적 I/O를 사용하여 페이지를 검색하고 미리 읽기를 수행합니다

서버가 테이블을 읽지 않고 인덱스를 스캔할 수 있으면, 일단 이런 시도를 먼저 합니다. 이것은 인덱스가 커버링 인덱스(쿼리를 만족시키는 데 필요한 모든 필드를 가진 인덱스)인 경우에 유용합니다. 서버는 정렬된 순서가 아닌 디스크 순서대로 B 트리 인덱스를 읽어 쿼리를 수행합니다. 이럴 순차적 읽기는 성능을 향상시킵니다.

큰 I/O

SQL Server 7.0에서 데이터베이스 페이지는 이전 버전의 2 KB에서 늘어난 8 KB입니다. 또한 SQL Server는 16 KB에서 늘어난 64 KB 크기 익스텐트 단위로 데이터를 읽습니다. 이러한 변화는 서버에서 단일 I/O 요청시 더 많은 양의 데이터를 읽도록 하여 성능을 향상시킵니다. 이는 대용량 데이터베이스(VLDB)와 의사 결정 지원 쿼리에 아주 중요합니다. 이 쿼리에서 단일 요청은 많은 수의 행을 처리합니다.

미리 읽기 스캔

SQL Server 7.0는 실제 쿼리 프로세서 요청에 앞서 여러 개의 익스텐트를 읽어 스트라이프 디스크 세트의 향상된 이점을 취합니다. 그 결과 힢 테이블과 B 트리 인덱스의 스캔이 더 빨라집니다.

프리패치 힌트

순차적 디스크 스캔은 용량이 큰 데이터의 스캔 속도를 향상시킵니다. SQL Server 7.0은 또한 넌클러스터 인덱스를 사용하여 데이터를 가져옵니다.

넌클러스터 인덱스를 사용하여 데이터를 검색할 때, 해당 인덱스는 특정 값을 찾습니다. 해당 값을 찾으면 인덱스가 디스크 주소를 가리킵니다. 일반적인 접근 방식은 디스크 주소가 제공되면 해당 행에 대한 I/O를 즉시 실행하는 것입니다. 그 결과 행마다 하나의 동기화 I/O가 생기고, 쿼리를 평가하기위해 한 번에 많아야 하나의 디스크가 작동합니다. 이는 striped 디스크 세트를 이용하지 않습니다.

SQL Server 7.0은 다른 접근 방식을 취합니다. 계속해서 넌클러스터 인덱스에서 더 많은 레코드 포인터들을 찾습니다. 많은 포인터가 모아지면, 서버는 스토리지 엔진에 프리패치 힌트를 제공합니다. 이들 힌트는 스토리지 엔진에 이러한 특정 레코드가 곧 필요하게 될 것이라는 것을 알려 줍니다. 이제 스토리지 엔진은 다중 작업을 동시에 수항하기 위해 스트라이프 디스크 세트를 이용하여, 여러 I/O를 동시에 수행합니다.

정렬 향상

쿼리 프로세서의 많은 영역은 병합 조인, 인덱스 작성, 스트림 계산 등의 정렬 알고리즘에 의존합니다. 정렬 성능은 SQL Server 7.0에서 보다 엄청나게 향상되었습니다.

수많은 내부 향상으로 보다 간단한 비교, 더 큰 I/O 작업, 비동기 I/O, 큰 메모리 등 각 정렬 작업을 향상시킵니다. 또한, SQL Server 7.0은 입력과 출력 면에서 정렬 작업과 쿼리 작업 간에 데이터를 이동시킵니다. 따라서 SQL Server 7.0에서는 전통적으로 SQL Server가 일반적으로 사용하던, 중간 작업 테이블을 작성하고 스캔해야 하는 쿼리 계획 단계가 없어도 됩니다.

병합 조인, 해쉬 조인 및 해쉬 팀

SQL Server 6.5는 중첩된 루프 반복이 사용되었습니다. 이는 하나의 주문 레코드에서 서너 개의 주문 라인 항목으로 이동하는 것과 같은 행별 탐색에 아주 좋습니다. 그러나 일반적인 데이터 웨어하우스 쿼리와 같이 많은 수의 레코드 조인에는 비효율적입니다.

SQL Server 7.0은 병합 조인, 해쉬 조인, 해쉬 팀 등 세 가지 새로운 기술을 도입하였습니다. 해쉬 팀은 다른 관계형 데이터베이스에서는 사용이 불가능한 중요한 혁신입니다.

병합 조인

병합 조인은 동시에 두 개의 정렬된 입력을 넘겨 내부(inner) 조인, 외부(outer) 조인, 세미 조인, 교집합, 유니온 등의 논리 작업을 수행합니다. 병합 조인은 B 트리 인덱스의 정렬된 스캔을 이용하며, 일반적으로 조인 필드가 인덱스화되고 인덱스에 표시된 컬럼이 쿼리를 커버할 경우에 사용하는 방법입니다.

해쉬 조인

해쉬 조인은 반복적인 랜덤 함수를 기본으로, 입력 값을 해쉬하고, 해쉬 테이블에서 일치하는 값을 비교합니다. 사용 가능 메모리보다 작은 입력의 경우, 해쉬 테이블은 메모리로 남으며, 더 큰 입력의 경우, 디스크상의 오버플로 파일이 사용됩니다. 해슁은 특히 중간 결과처럼 일반적으로 크고 인덱스되지 않은 테이블을 선택하는 방법입니다.

해슁 작업은 GROUP BY 절, distinct, 교집합, 유니온, 차이, 내부 조인, 외부 조인 및 세미 조인을 처리할 때 사용할 수 있습니다. SQL Server 7.0은 메모리 해슁에 최적화된 캐쉬, 대용량 메모리, 반복되는 파티셔닝, 하이브리드 해슁, 비트 벡터 필터링 및 역할 반전(role reversal) 등 잘 알려진 해슁 기법을 모두 구현합니다.

해쉬 팀

SQL Server 7.0에 있어서의 하나의 혁신은 해쉬 팀입니다. 많은 쿼리들은 다중 실행 단계로 구성되어 있어서, 가능하면 쿼리 옵티마이저는 다중 단계를 거칠 때 비슷한 작업을 이용해야 합니다. 예를 들어, 각 파트 번호와 각 제공자에 대해 얼마 만큼의 주문 라인 항목이 입력되어 있는지 알고 싶을 수 있습니다.

SELECT l_partkey, count (*)

FROM lineitem, part, partsupp

WHERE l_partkey = p_partkey and p_partkey = ps_partkey

GROUP BY l_partkey

그 결과, 쿼리 프로세서는 실행 계획을 생성하게 됩니다.



이 쿼리 계획은 lineitem 테이블과 partsupp 테이블 간의 병합 내부(merge inner) 조인을 수행합니다.

개수(스트림 연산)를 계산한 다음 그 결과를 part 테이블과 조인합니다. 이 쿼리에는 정렬 작업이 필요 없습니다. 이 쿼리는 인덱스에 정렬된 스캔을 사용하여 lineitem 및 partsupp 테이블에서의 정렬된 순서로 레코드를 검색하기 시작합니다. 이로 인해 병합 조인에 정렬된 입력을 제공하고, 그 결과 연산에 정렬된 입력을 제공합니다. 이 결과는 다시 최종 병합 조인에 정렬된 입력을 제공합니다.

Interesting ordering은 연산자에서 연산자로 이동하는 중간 결과의 순서를 추적하여 정렬 작업을 피하는 이상적인 계획으로서, 현재 나와있는 모든 주요한 쿼리 프로세서에 의해 구현됩니다. 그러나 SQL Server 7.0은 이보다 더 나아가 해쉬 조인에 동일한 개념을 적용합니다. 동일한 쿼리를 고려하면서, 이렇게 생각해 보기로 합시다. lineitems의 중요한 인덱스가 삭제되었으며, 이로 인해 이전 계획이 대량의 lineitems 테이블에서의 비싼 정렬 작업이 요구된다고 가정해 봅시다.



이 쿼리 계획은 병합 조인 대신 해쉬 조인을 사용합니다. 병합 조인 중 하나는 삭제된 인덱스의 영향을 받지 않으므로 여전히 빠르게 진행됩니다. 두 해쉬 작업은 루트와 팀원으로서 특별하게 표시됩니다. 데이터가 해쉬 조인에서 그룹핑 작업으로 옮겨갈 때, 해쉬 조인의 파티션 행에 대한 작업은 그룹화된 작업에서 활용될 수 있습니다. 이렇게 하면 그룹핑 작업의 입력 하나에 대한 오버 플로우 파일을 없앨 수 있습니다. 그리하여 쿼리에 대한 I/O 비용을 줄일 수 있습니다. 복잡한 쿼리에 대해 보다 빨리 처리할 수 있는 이점이 있습니다.

인덱스 교집합(Intersections)

Microsoft SQL Server 6.5는 쿼리에 다중 예측이 가능하더라도 각 테이블에서 최상의 인덱스 하나만을 선택하였습니다.

SQL Server 7.0은 각 인덱스를 기본으로 데이터의 작은 하위세트를 선택한 다음 ,두 서브세트의 교집합을 연산합니다.(즉, 모든 조건에 맞는 행들만 되돌립니다.)

예를 들어, 특정 범위 고객의 주문 총수와 주문 날짜를 계산하고 싶다고 해 봅시다.

SELECT count (*)

FROM orders

WHERE o_orderdate between ‘9/15/1992’ and ‘10/15/1992’ and

o_custkey between 100 and 200

SQL Server 7.0은 o_custkey 및 o_orderdate 의 인덱스를 모두 활용한 다음, 조인 알고리즘을 사용하여 두 서브세트 사이의 인덱스 교집합을 구합니다. 이 실행 계획은 orders 테이블에서 두 인덱스를 모두 활용합니다.



인덱스 조인

인덱스 교집합의 변형이 인덱스 조인입니다. 인덱스를 사용할 때는 주어진 쿼리를 위해 모든 컬럼이 필요할 경우에도 전체 행을 가져올 필요는 없습니다. 이런 인덱스는 쿼리에 필요한 컬럼을 모두 포함하기 때문에 이를 covering index라고 합니다.

covering index는 일반적으로 많이 알려진 기술입니다. SQL Server 7.0은 이를 인덱스 교집합에 적용하여 이 기술을 더 끌어올렸습니다. 쿼리를 커버할 수 있는 단일 인덱스는 없지만 다중 인덱스가 함께 이 쿼리를 커버할 수 있다면, SQL Server는 이 인덱스들을 조인할 것을 고려합니다. 어떤 대안을 선택할 것인지는 쿼리 옵티마이저의 비용 속성에 달려있습니다.



병렬 계획

Microsoft SQL Server 7.0는 단일 쿼리를 여러 하위 작업으로 쪼개어 SMP 시스템의 다중 프로세서를 통해 분배하는 실행하는 능력인 쿼리 내부(intra-query) 병렬성을 도입합니다.

이 아키텍처는 실행 중인 다중 병렬 스레드를 만드는 진정한 병렬화 작업을 합니다. 각 작업(스캔, 정렬 또는 조인)은 병렬성에 대해 알지 못하지만, 단지 병렬화 작업과 결합되어 있기 때문에 병렬로 수행되어 “parallel everything”이 될 수 있습니다.

parallel everything의 예외인 parallel updates는 Microsoft에서 차후의 SQL Server 버전에 추가할 계획입니다. 기타 모든 작업(스캔, 정렬, 조인, GROUP BYs)은 병렬로 처리됩니다.

SQL Server는 현재 SMP 시스템에서 실행되고 있는지 검사하고, 병렬 쿼리의 각 인스턴스에 최상의 병렬성을 지정합니다. 일단 쿼리가 실행되기 시작하면 완료될 때까지 동일한 수의 스레드를 사용합니다. SQL Server는 프로시저 캐시에서 병렬 쿼리 실행 계획이 검색될 때마다 최적의 스레드 수를 결정합니다. 그 결과 쿼리를 한 번 실행하면 단일 스레드를 사용할 수 있으며, 동일한 쿼리를 한 번 더 실행하면 둘 이상의 쿼리를 사용할 수 있습니다.

병렬성에 영향을 주는 요인

다음 질문들에 대한 답에 따라 SQL Server 7.0에서 병렬 쿼리 과정을 사용할 것인지 아닌지가 자동으로 결정됩니다.

· SQL Server가 둘 이상의 프로세서가 장착된 컴퓨터(SMP 시스템)에서 실행되고 있습니까? 둘 이상의 프로세서가 장착된 컴퓨터만 병렬 쿼리를 이용할 수 있습니다.

· SQL Server 7.0 데스크톱, 스탠더드 또는 엔터프라이즈 판 중 어떤 것을 실행하고 있습니까? SQL Server 데스크톱 판은 두 개까지의 프로세서를 지원하고, 스탠더드 판은 네 개까지의 프로세서를 지원하고, 엔터프라이즈 판은 여덟 개까지의 프로세서를 지원합니다.

· SQL Server에서 활성화할 수 있는 동시 사용자의 수는? SQL Server는 CPU 활용을 모니터하고 쿼리 시작 시간에 병렬 정도를 조정합니다. CPU의 사용량이 많으면 더 낮은 병렬성이 선택됩니다.

· 병렬 쿼리 실행에 사용 가능한 충분한 메모리가 있습니까? 각 쿼리는 일정한 양의 메모리가 있어야 실행할 수 있습니다. 병렬 쿼리는 비병렬 쿼리보다 많은 메모리가 필요합니다. 병렬 쿼리를 실행하는 데 필요한 메모리의 양은 병렬 정도에 따라 늘어납니다. 지정된 병렬 정도에 대한 병렬 계획의 메모리 필요 요건이 만족스럽지 않으면, SQL Server가 자동으로 병렬의 정도를 감소시키거나 지정된 표준 작업량 컨텍스트에 대한 병렬 계획이 완전히 취소되고 직렬 계획을 수행합니다.

· 실행중인 쿼리의 종류는? 많은 CPU 사이클을 소모하는 쿼리는 병렬 쿼리에 아주 적합합니다. 예를 들면 대용량 테이블의 조인, 실질적인 계산 및 대형 결과 세트의 정렬등이 여기에 해당합니다. 트랜잭션 처리 애플리케이션에서 자주 발견되는 간단한 쿼리가 병렬로 수행하는 데 필요한 추가 조합을 찾으면 잠재 성능을 능가하게 됩니다. 병렬의 이점이 있는 쿼리들과 이점이 없는 쿼리들을 구분하기 위해, SQL Server는 측정된 쿼리 실행 비용과 병렬 비용 임계값을 비교합니다. 관리자는 기본 비용 임계값을 변경할 수 있지만, 권장할 만하지는 않습니다.

· 지정된 스트림에 충분한 행이 있습니까? 쿼리 옵티마이저가 스트림에서 확인한 행 수가 너무 적으면 병렬 연산자를 도입하지 않습니다. 병렬 실행에 드는 시작, 분배 및 조정 비용이 병렬 실행으로 얻게 되는 이익을 넘으면 병렬 실행은 수행되지 않고 순차적 계획을 실행합니다.

기타 병렬 작업

병렬 쿼리 외에도 Microsoft SQL Server 7.0은 다중 클라이언트, 병렬 백업 및 병렬 복구를 사용하여 병렬 로드를 지원합니다. 자세한 내용은 이 문서의 “Microsoft SQL Server 7.0으로 대용량 DSS 데이터베이스 구현” (파트 번호 098-81102)과 “벤치마크: 온라인 데이터베이스 백업 중의 많은 업무 처리량” (파트 번호 098-812333)을 참고하십시오.

쿼리 최적화

Microsoft SQL Server 7.0에 포함된 혁신적이고 최첨단 쿼리 옵티마이저에 대한 많은 측면이 있습니다.

다중 단계 최적화

SQL Server 7.0 쿼리 옵티마이저는 다중 단계로 처리됩니다. 먼저, 쿼리를 만족시키는 간단하면서도 합리적인 계획을 찾습니다.

해당 계획이 비용 임계값(예: 몇 분의 일초)보다 시간이 적게 걸리면 쿼리 옵티마이저가 보다 효율적인 계획을 찾느라고 애쓰지 않습니다. 이렇게 함으로써 쿼리 옵티마이저가 계획을 실행하는데 필요한 것보다 더 많은 리소스를 최적의 계획을 찾는데 사용하는 과최적화를 방지합니다.

선택한 첫 계획이 비용 임계값보다 더 많은 시간이 걸리면, 옵티마이저가 계속해서 다른 계획을 찾아보고 항상 최소한의 비용이 드는 계획을 선택합니다. 다중 단계를 사용하면 가장 효율적인 계획을 선택할 때 걸리는 시간과 해당 계획을 최적화할 때 걸리는 시간 사이에 균형을 이룰 수 있습니다.

자동 파라미터

대부분의 쿼리 프로세서를 사용하면 실행 계획을 미리 컴파일하여 저장할 수 있습니다. 예제는 스토어드 프로시저를 컴파일하는 것입니다.

미리 컴파일한 작업은 실행 계획을 재사용할 수 있으므로 더 효율적입니다. 실행 계획은 사용자가 매개변수를 파라미터로 보낼 수 있게 합니다. 반복된 실행을 위한 준비된 요청을 위한 새로운 ODBC 인터페이스도 이런 효율성을 활용합니다.

그러나 많은 상업용 애플리케이션과 임의의(ad hoc) 쿼리는 스토어드 프로시저를 사용하지 않고 동적 SQL을 사용합니다. SQL Server 7.0은 자동 파라미터라는 새 기능을 구현하는데, 이 기능은 동적 SQL용으로 만든 계획을 캐시하고, 상수를 파라미터로 전환합니다. 결과적으로 스토어드 프로시저의 많은 효율성을 제공하여 스토어드 프로시저를 사용하지 않는 애플리케이션에 대해서 조차도 보다 적은 컴파일 노력이 들게 됩니다.

SQL Server 7.0은 또한 파라미터화된 쿼리의 완전한 지원을 합니다. 여기서 애플리케이션은 파라미터를 식별합니다. 이는 ODBC, OLE DB 및 준비/실행(prepare / execute)에 일반적입니다.

삼단논법

처음 수학을 접할 때 배웠던 삼단논법에 대해 기억하실 겁니다. A = B이고 B = C이면 삼단논법에 의해 A = C입니다. 이 속성을 쿼리에도 적용할 수 있습니다.

SELECT *

FROM part, partsupp, lineitem

WHERE ps_partkey = l_partkey and l_partkey = p_partkey and

ps_availqty > l_quantity and ps_supplycost > p_retailprice

ps_partkey와 p_partkey는 둘 다 l_partkey와 같기 때문에, ps_partkey는 p_partkey와 같아야 합니다. 쿼리 프로세서는 세 번째 조인 속성(ps_partkey = p_partkey)을 끌어내어 이를 이용합니다. 예를 들어, 이 쿼리에서 쿼리 프로세서는 parts 테이블의 부분키를 partsupp 테이블의 부분키와 조인합니다. 이 특정 조인 속성이 쿼리에 지정되어 있지 않는 경우에도 마찬가지입니다. 이는 바로 삼단논법 때문입니다.



중첩 쿼리

상호 관련된 하위 쿼리는 모든 SQL 쿼리 프로세서에 대한 특수한 도전을 제시합니다. SQL Server는 일부 특정 기술을 상호 관련된 하위 쿼리에 적용하여, 가능하면 이것들을 세미 조인으로 균등화합니다. 균등화(flattening)의 이점은 모든 조인 알고리즘을 적용할 수 있다는 것입니다. 대형 쿼리의 경우, 이 말은 쿼리 옵티마이저가 덜 효율적인 중첩 반복 조인을 사용하지 않고, 해쉬 조인이나 병합 조인을 고려할 수 있다는 뜻입니다.

GROUP BY 절 이동

SQL 표준에서는 특정 순서대로 쿼리를 처리해야 합니다.

1. FROM과 WHERE 절을 실행합니다.
2. GROUP BY 절을 사용하여 데이터를 줄입니다.
3. HAVING 절에 있는 조건을 적용합니다.

동일한 결과를 만들어 내는 계획도 정확합니다. 그러므로 일부 쿼리에서는 WHERE 절에 하나 이상의 조인 작업이 필요하기 전에, GROUP BY 절을 더 빨리 실행할 수 있어서 조인 입력이나 조인 비용이 줄어듭니다. 이것을 GROUP BY 절이라고 합니다. 예를 들어 봅시다.

SELECT c_name, c_custkey, count (*), sum (l_tax)

FROM customer, orders, lineitem

WHERE c_custkey = o_custkey and o_orderkey = l_orderkey and

o_orderdate between ‘9/1/1994’ and ‘12/31/1994’

GROUP BY c_name, c_custkey

GROUP BY 절을 살펴보면, 쿼리 프로세서가 기본 키 c_custkey가 c_name를 결정하는 것을 알기 때문에, c_custkey 외에 c_name에 대해 그룹을 지정할 필요가 없습니다. 그런 다음 쿼리 옵티마이저는 c_custkey과 o_custkey에서의 그룹핑하는 것이 동일한 결과를 생성한다는 것을 알아냅니다. orders 테이블에는 고객 키(o_custkey)가 있기 때문에, 쿼리 프로세서는 customer 테이블로 조인되기에 앞서 orders 테이블에 대한 레코드를 가질 때 고객 키별로 그룹화할 수 있습니다. 다음 실행 계획에서 명확하게 볼 수 있습니다.



쿼리 프로세서는 먼저 orders 테이블(지정한 날짜 범위 내)과 lineitem 테이블을 병합 조인하여 모든 주문 라인 항목을 가져옵니다. 두 번째 단계는 작업을 그룹으로 묶는 해쉬 계산입니다. 이 단계에서 SQL Server는 고객 키 수준에서 주문 라인 항목을 합하고, 총계를 낸 다음 l_tax의 합계를 계산합니다. SQL Server는 그런 다음 해쉬 조인의 출력을 정렬하고 customer 테이블로 조인하여 요청된 결과를 만들어 냅니다. 이 쿼리 계획의 이점은 최종 조인의 입력이 초기의 그룹화 작업으로 인해 줄어든다는 것입니다.

파티셔닝 뷰

Microsoft SQL Server 7.0은 파일그룹을 사용하여 파티셔닝을 지원합니다. 이 아키텍처는 파티션의 이점을 취하는데, 특히 전체 데이터베이스보다 더 세밀한 수준에서 관리하는 능력이 있습니다. 이 아키텍처는 SQL Server의 차후 버전에서 디스크상 파티셔닝을 지원합니다. 그러나 대형 의사 결정 지원 쿼리의 경우, SQL Server 7.0은 파티셔닝 뷰를 구현하여, 데이터베이스 관리자가 제한자(특히, 파티션마다 테이블 하나)로 다중 테이블을 만들 수 있습니다. 그런 다음 테이블은 파티셔닝 뷰를 통해 논리적으로 다시 결합됩니다. 다음은 예제입니다.



CREATE table Sales96Q1 … constraint “Month between 1 and 3”

CREATE table Sales96Q2 … constraint “Month between 4 and 6”



CREATE view Sales96 as

SELECT * from Sales96Q1 union all

SELECT * from Sales96Q2 union all



DDL(데이터 정의 언어)로 네 가지의 테이블을 만들 수 있습니다. 판매 분기마다 하나씩 만들 수 있는데 각각은 해당 제한자를 가지고 있습니다. 그런 다음 DDL은 네 가지 테이블을 모두 재결합하는 뷰를 만듭니다. 프로그래머들은 업데이트를 위해 파티셔닝을 잘 알고 있어야 하지만, 의사 결정 지원 쿼리의 경우에 파티셔닝은 공개되어 있습니다. 쿼리 프로세서에서 뷰 Sales96에 대해 쿼리를 받으면, 자동으로 쿼리의 제한자 범위를 벗어나는 테이블을 식별하여 제거합니다.

SELECT *

FROM Sales96 -- remember, this view has four tables

WHERE s_date between ‘6/21/1996’ and ‘9/21/1996’

이 쿼리를 실행하면 쿼리 프로세서가 뷰에서 두 가지 테이블(Sales96Q2와 Sales96Q3)만 사용하는 계획을 생성합니다. WHERE 절이 다른 두 테이블에서 제한자를 부정하기 때문입니다. 따라서 이 쿼리에는 부적합한 것이 됩니다. 더욱이 개별 분기에 다른 액세스 경로가 사용될 수 있습니다( 예: Q2에서 몇일 동안의 자료를 위한 인덱스 스캔, Q3을 위한 테이블 스캔). 이것은 잘 알려진 컬럼에서 대형 테이블의 하위 집합을 선택하는 쿼리의 성능을 향상시킬 때 유용한 방법입니다. 시간과 위치는 일반적인 예제입니다.

SQL Server는 제한자가 선택 조건을 부정할 때 빈 결과를 모두 검색합니다. 관리자가 뷰를 선언하지 않은 경우에 조차도 선택 조건이 제한자와 맞지 않으면, 옵티마이저가 이것을 인식하고 적절한 계획을 생성합니다.

스타 쿼리

의사 결정 지원용으로 설계된 데이터베이스, 특히 데이터 웨어하우스 및 데이터 마트는 OLTP 데이터베이스와 아주 다른 테이블 구조를 가진 경우가 많습니다. 일반적으로는 사용자가 직관적으로 데이터베이스의 정보를 탐색하도록 하고, 대형 쿼리와 ad hoc 쿼리에 더 나은 성능을 제공하기 위한 데이터베이스 스키마 유형인 스타 스키마를 구현하면 됩니다.

스타 스키마는 정보를 사실(분석되는 내용의 핵심인 수치 데이터), 사실의 크기 및 속성으로 분류할 수 있는 관찰에서 시작됩니다. 사실의 예로는 판매, 단위, 예산 및 예측 등이 있습니다. 크기의 예로는 지리, 시간, 제품 및 판매 채널이 있습니다. 사용자는 “이러한 크기로 이 사실을 확인하고 싶습니다.” 또는 “분기별로 판매되는 판매량과 단위를 보고 싶습니다.”라는 식으로 말하며 자신의 질문을 표현합니다.

스타 스키마는 데이터를 중심 fact table과 이를 둘러싸는 dimension table로 구성하여 이러한 관찰을 이용합니다.



Microsoft SQL Server 7.0에는 스타 스키마에 대해 쿼리를 최적화할 수 있는 여러 기술이 들어 있습니다. 쿼리 프로세서는 자동으로 이 쿼리들을 인식하고, 여기서 설명하는 기술과 이 기술을 결합하여 적용합니다. 어떤 기술을 적용할 것인지 선택하는 것은 전적으로 비용에 달려 있으며, 최적화를 할 때는 필요한 힌트가 없습니다.

스타 스키마의 테이블에는 같은 수의 레코드가 들어 있지 않습니다. 일반적으로 팩트(fact) 테이블에는 더 많은 레코드가 들어 있습니다. 이 차이점은 많은 쿼리 최적화 기술에 중요해지고 있습니다.

간단한 실행 전략은 팩트 테이블 전체를 읽고 차례로 각 디멘젼(dimension) 테이블에서 조인하는 것입니다. 이것은 쿼리에 필터 조건이 지정되어 있지 않은 경우 아주 합리적인 전략입니다. 그러나 필터 조건이 제시되어 있으면 스타 쿼리 최적화가 인덱스를 완전히 이용함으로써 팩트 테이블 전체를 읽지 않아도 되도록 해줍니다.

순서 쌍(Cartesian Products) 및 복합 인덱스

디멘젼 테이블은 팩트 테이블보다 보통 더 작은 레코드를 가지므로, 순서 쌍을 계산하고 구해진 값으로 다중컬럼 인덱스의 팩트 테이블 행을 조회할 때 사용합니다.

이 기술은 예제를 보면 가장 이해하기 쉽습니다. 앞서 예제에서 팩트 테이블인 sales 테이블에 1천만개의 행이 있다고 가정합시다.

period 테이블에는 20개 행, market 테이블에는 5개 행, product 테이블에는 200개 행이 있습니다. 사용자는 프런트 엔드 도구를 사용하여 이 쿼리를 생성합니다.

SELECT sales.market_id, period.period_id, sum(units), sum(dollars)

FROM sales, period, market

WHERE period.period_id = sales.period_id and

sales.market_id = market.market_id and

period.period_Desc in (‘Period2’,’Period3’,’Period4’,’Period5’)

and market.market_Desc in (‘Market1’,’Market2’)

GROUP BY sales.market_id, period.period_id

간단한 방법은 period 테이블을 sales 테이블에 조인하는 것입니다. 데이터를 균일하게 분배하며, 입력은 1천만 행, 출력은 4/20(가능한 20개 기간 중 4개) 또는 2만 행이 있다고 가정합니다. 해쉬 조인이나 병합 조인을 사용하고, 팩트 테이블에 1천만 행을 전부 읽거나 인덱스 조회로 2만 행을 검색하여 수행할 수 있습니다. 이 때 비용이 적게 드는 쪽을 선택하도록 합니다. 그런 다음 이 부분적인 결과는 감소된 market 테이블로 조인되어 800K의 출력 행을 생성하여 마침내 집계가 됩니다.

예를 들어, 팩트 테이블의 period_id 또는 market_id 컬럼에 다중 컬럼 인덱스가 있으면, 순서 쌍을 사용할 수 있습니다. period 테이블에 4행이 선택되어 있고 market 테이블에 2행이 선택되어 있으므로 순서 쌍은 8행이 됩니다. 이 8의 값 조합은 출력의 800K 행을 조회할 때 사용됩니다. 다중 컬럼 인덱스는 이런 방법으로 사용되며 스타 인덱스라고 하는 경우도 합니다.

세미 조인 감소 (Semi-join Reduction) 및 인덱스 교집합

팩트 테이블에 대한 조인이 복합 인덱스에 포함된 필드가 아닌 다른 필드에서 일어나면, 쿼리 옵티마이저는 다른 인덱스를 사용하여 조인으로부터 각 디멘젼 테이블까지 자격있는 컬럼의 교집합을 연산함으로써 팩트 테이블로부터 읽을 행 수를 줄일 수 있습니다.

예를 들어, 선택 내용이 period_id와 product_id에 있으면, 쿼리 옵티마이저는 원하는 두 필드 period_id와 product_id가 인덱스의 선두 하위 집합이 아니므로 복합 인덱스를 사용할 수 없습니다. 그러나 period_id와 product_id에 별도의 단일 컬럼 인덱스가 있으면, 옵티마이저는 period 테이블과 sales 테이블 사이의 조인(2백만 인덱스 항목 검색)을 선택하게 됩니다. 또 별도로 product 테이블과 sales 테이블 사이의 조인(4백만 인덱스 항목 검색)을 선택하게 됩니다. 두 경우 모두 이 예비적인 조인이 sales 테이블의 전체 행이 아닌 sales 테이블에 대한 레코드 ID 세트를 계산합니다. sales 테이블에서 실제 행을 검색하기 전에(이 과정이 가장 많은 비용이 든다는 것을 명심하십시오.), 두 세트의 교집합이 연산되어 실제 자격있는 행을 결정합니다. 두 조인 모두를 만족하는 행인 8십만행의 중간 결과에서 끝나며, 결국 이 행들은 sales 테이블에서 실제로 읽을 수 있습니다.

결합된 기술

세미 조인 감소가 순서 쌍(cartesian product)과 복합 인덱스로 결합되는 경우가 가끔 있습니다. 예를 들어, 3개의 디멘전 테이블에서 선택하는 경우, 세 테이블 중 두 테이블이 복합 인덱스의 첫 필드이며 세 번째 디멘젼에 개별 인덱스가 있으면, 쿼리 옵티마이저가 순서 쌍을 사용하여 첫 번째 두 조인을 만족시키고 세미 조인을 사용하여 세 번째 조인을 만족한 다음 결과를 결합합니다.여러 요인들이 이러한 기술의 효율성에 영향을 줍니다. 이러한 요인으로는 기본 테이블에 사용되고 비교되는 인덱스의 크기, 기본 테이블에서 행을 조회할 필요성 제거하면서 사용되는 인덱스 세트가 쿼리에서 필요로 하는 모든 컬럼을 포함할 지의 여부 등이 있습니다.이 계획이 병렬성에 대한 비용 임계값보다 더 많은 비용이 들면 스캔, 조인, 교집합 및 행 페치 등 모든 필요한 작업이 다중 스레드에 의해 병렬로 실행될 수 있습니다.

최적화된 업데이트

테이블의 행이 업데이트되면 해당 테이블의 인덱스도 업데이트됩니다. OLTP 작업과 같이 소규모로 업데이트하는 경우에는 기본 테이블의 각 행을 업데이트할 때 행별로 인덱스를 업데이트하는 것이 적절합니다.

데이터 웨어하우스 새로고침과 같이 대규모로 업데이트하는 경우에는 행별 업데이트가 부적절하므로, 인덱스 레코드에 대한 많은 양의 임의 I/O가 생깁니다. 더 나은 방법은 기본 테이블이 모두 업데이트될 때까지 인덱스 업데이트 작업을 연기한 다음, 인덱스마다 변경 내용을 미리 정렬하고 동시에 모든 변경 내용을 인덱스로 병합하는 것입니다. 이렇게 하면 각 인덱스 리프 페이지를 기껏해야 한 번 터치하게 하고 SQL Server가 각 B 트리 인덱스를 차례로 지나가도록 합니다.

이것이 비용이 가장 적게 드는 방법이면 쿼리 옵티마이저가 이 방법을 취하게 됩니다. 대형 데이터 웨워하우스가 보다 효율적으로 새로 고쳐진다는 이점이 있습니다.

쿼리 옵티마이저는 또한 (인덱스) 중첩 루프 조인, 병합 조인, 해쉬 조인 간에 비용 기반 선택을 하여, 참조 무결성 제한자를 실행하는데 필요한 조인 작업을 계획합니다.

분산 쿼리

데이터를 지역적으로 저장하고 검색하는 것 외에 Microsoft SQL Server 7.0은 다른 많은 데이터 저장소, 관계형 데이터베이스와 비관계형 데이터 소스 모두에 대한 게이트웨이로서 사용할 수 있습니다.

SQL Server 7.0은 분산 쿼리를 수행합니다. 즉, 둘 이상의 서버로부터 데이터를 포함하는 쿼리를 수행합니다. 이 쿼리는 서버를 통해 검색과 업데이트를 수행하고, MS DTC(Microsoft Distributed Transaction Coordinator)를 사용하여 노드들에 대한 트랜잭션 의미를 확실하게 합니다. 서버들에 대한 보안도 유지합니다.

인덱스나 SQL 쿼리를 지원하는 원격 서버가 있으면 SQL Server 쿼리 옵티마이저가 각 원격 서버로 보낼 수 있는 가장 큰 쿼리를 지정합니다. 즉, 쿼리 옵티마이저는 가능한 최대 데이터 감소를 각 원격 서버에 지정합니다. 예를 들어, 원격 쿼리가 1백만개의 행을 가진 테이블에 대해 실행되지만 WHERE 절이나 연산에 의해 10개의 레코드만 되돌리는 것이라면, 1백만개의 행이 원격 서버에서 처리되고, 10개의 레코드만 네트워크를 통해 보내집니다. 이렇게 하면 네트워크 트래픽과 전체 쿼리 시간이 감소됩니다. 데이터 소스로 보내지는 일반적인 작업은 선택, 조인, 정렬 등입니다.

이기종 쿼리

분산 쿼리가 OLE DB 또는 ODBC 데이터 소스를 지원하는 이기종일 수 있습니다. SQL Server 7.0 CD에는 Oracle 7.x, Oracle 8.x, Microsoft Excel, Microsoft Access, dBASE, Paradox, Microsoft Visual FoxPro® 데이터베이스 개발 시스템 및 기타 관계형 데이터베이스에 대한 OBDC 게이트웨이용 OLE DB 드라이버가 들어 있습니다. 기타 서버 데이터베이스(IBM DB2, SYBASE 및 Informix)용 OLE DB 프로바이더는 협력업체를 통해 사용할 수 있습니다.

통과(Pass-through) 쿼리

원격 서버가 비 SQL 표준 구문을 지원하거나 원격 데이터 소스가 SQL이 아닌 쿼리 언어를 지원하면, OPENQUERY 연산자가 제공되어 쿼리 구문을 변경하지 않고 통과시킵니다.

쿼리 작업

서버의 향상된 쿼리 처리 기능 외에 Microsoft SQL Server 7.0은 또한 데이터베이스 쿼리로 작업할 수 있는 향상된 도구를 제공합니다.

쿼리 분석기(Query Analyzer)

SQL Server 7.0에는 데이터베이스 관리자나 개발자가 쿼리를 작성하고, 동시에 다중 쿼리를 실행하고, 결과를 보고, 쿼리 계획을 분석하고, 쿼리 성능을 향상시킬 수 있는 도움을 주는 대화식 그래픽 도구인 쿼리 분석기(Query Analyzer)가 있습니다. SHOWPLAN 옵션은 SQL Server 쿼리 옵티마이저에서 선택한 데이터 검색 방법을 그래픽으로 표시합니다. 이는 쿼리의 성능 특징을 이해하는 데 아주 유용합니다. 또한 쿼리 분석기는 쿼리를 효율적으로 처리할 수 있는 쿼리 옵티마이저의 능력을 향상시키는 인덱스화되지 않은 컬럼의 추가 인덱스나 통계를 제시해주기도 합니다. 특히, 쿼리 분석기는 통계를 읽은 것이 무엇인지 보여주므로 쿼리 옵티마이저가 선택성을 예측하게 해줄 뿐 아니라 단 몇 번만의 클릭으로 이러한 통계를 작성할 수 있도록 해줍니다.

쿼리 가버너(Query Governor)

쿼리 비용은 특정 하드웨어 구성에서 쿼리를 실행하는 데 필요한 초 단위의 측정된 경과 시간을 말합니다. 다른 하드웨어 구성에서는 비용 단위와 경과 시간 사이에 강한 상호 관계가 있습니다. 그렇지만 비용 단위는 초와 다릅니다. query governor를 사용해서 한 쿼리에 대해 최대 한계 비용을 지정할 수 있습니다. 이 한계를 넘는 쿼리는 실행되지 않습니다.query governor는 실제 경과 시간이 아닌 측정된 쿼리 비용을 기본으로 하므로, 런타임 오버헤드를 가지지 않습니다. 또한 미리 지정한 한계에 도달할 때까지 쿼리들을 실행하는 것이 아니라 시작하기 전에 오래 실행되는 쿼리를 중지합니다.

SQL Server Profiler

Microsoft SQL Server Profiler는 그래픽 도구로서 시스템 관리자가 엔진 이벤트를 모니터할 때 사용할 수 있습니다. 엔진 이벤트의 예로는 다음이 있습니다.

· 로그인 연결, 실패, 연결 해제

· SQL SELECT, INSERT, UPDATE, DELETE 문 처리

· 원격 프로시저 호출(RPC) 배치(batch) 상태

· 스토어드 프로시저의 시작과 끝

· 스토어드 프로시저 내의 명령문의 시작 또는 끝

· SQL 배치(batch)의 시작 또는 끝

· 데이터베이스 개체에서 걸리거나 풀린 잠금

· 열려있는 커서

· 쿼리 옵티마이저가 지정 선택성을 사용하도록 하는 잃어버린 통계

나중에 분석할 수 있도록 데이터의 각 이벤트를 파일이나 SQL Server 테이블로 캡처하고 저장할 수 있습니다. 이벤트 데이터는 적절한 하위 집합만 수집할 수 있도록 필터할 수 있습니다. 예를 들어, 특정 데이터베이스에 영향을 주는 이벤트 또는 특정 사용자에 대한 이벤트만 수집할 수 있습니다. 이 때 나머지는 모두 무시됩니다. 30초 이상이 걸려 실행되는 쿼리에 대해서만 데이터를 수집할 수도 있습니다.

SQL Server Profiler를 사용하면 캡처한 이벤트 데이터를 SQL Server에 대해 재생할 수 있으므로, 저장된 이벤트가 처음으로 발생한 것처럼 효율적으로 재실행할 수 있습니다. 문제가 될만한 이벤트를 모두 캡처한 다음 테스트 시스템에서 이벤트를 재실행하고, 문제를 복제하여 따로 떼어놓고 SQL Server의 문제를 해결할 수 있습니다.

인덱스 튜닝 마법사

Microsoft SQL Server 인덱스 튜닝 마법사는 사용자의 작업량을 분석하여 각자의 데이터베이스에 맞는 최적의 인덱스 구성을 해주는 강력한 새 도구입니다.

인덱스 튜닝 마법사의 기능은 다음과 같습니다.

· 쿼리 옵티마이저의 비용 계산을 사용하여 최상의 인덱스 혼합을 비교, 대조 및 선택하기

· 데이터베이스에 대한 워크로드 (추적 파일 또는 SQL Script)에 맞는 최상의 인덱스 혼합 추천하기

· 인덱스, 작업량, 사용 테이블 및 쿼리 비용 분석 제공하기

· 전체 작업량 튜닝. 유지 비용을 줄이기 위해 기존 인덱스를 없애는 작업도 포함됩니다.

· 기존 쿼리를 없애지 않고 일련의 문제 쿼리를 위한 데이터베이스 튜닝

· 다른 디스크 공간 제한자에 대한 인덱스 구성 추천 내용 프로토타이핑

인덱스 튜닝 마법사는 인덱스되지 않은 컬럼에서 보다 효율적인 새로운 인덱스를 만들기 위해 비효율적인 인덱스를 없애는 데 사용할 수 있는 SQL 문을 만듭니다. SQL 문은 필요한 경우 수동으로 실행할 수 있도록 저장해 둘 수 있습니다.

자동 통계 작성 및 새로 고침

인덱스를 만들 때 Microsoft SQL Server는 자동으로 인덱스되지 않은 컬럼에서 값의 분배에 관한 통계 정보를 저장합니다.

SQL Server 7.0은 또한 인덱스되지 않은 컬럼에서의 통계를 지원합니다. 쿼리 옵티마이저는 이러한 통계를 사용하여 중간 쿼리 결과 크기와 쿼리용 인덱스 사용 비용을 측정합니다.

쿼리 옵티마이저가 쿼리를 최적화하기 위해 잃어버린 중요한 통계가 있는지 확인하는 경우, 자동으로 필요한 통계를 생성합니다. 이렇게 자동으로 생성된 통계는 데이터베이스에 저장되며 다른 쿼리를 최적화할 때 사용할 수 있습니다. 그러나 다시 필요로 하지 않으면 잠시 후 없어지게 됩니다. 더욱이 SQL Server는 테이블의 데이터가 변경되고 이 통계들의 날짜가 지나면 자동으로 통계 정보를 업데이트합니다.

통계는 샘플링을 통해 아주 효율적으로 생성되고 새로 고쳐집니다. 샘플링은 데이터 페이지 전체에 무작위로 수행되며, 테이블에서 가져오거나 통계에 필요한 컬럼을 포함하는 가장 작은 인덱스에 대한 클러스트되지 않은 인덱스에서 가져옵니다. 테이블의 데이터 볼륨과 변경되는 데이터 양은 통계 정보가 업데이트되는 빈도를 결정합니다. 예를 들어, 10,000개의 행이 있는 테이블이 있으면, 테이블에서 중요한 비율인 1,000개의 행이 변경될 때 이 테이블에 대한 통계를 업데이트해야 할 수도 있습니다. 그러나 1천만개의 행이 있는 테이블에서 1.000개의 행이 변경되는 것은 별로 중요하지 않습니다.

결론

이 문서는 Microsoft SQL Server 7.0 쿼리 프로세서에서의 혁신과 향상된 점을 설명합니다. SQL Server 7.0 쿼리 옵티마이저는 수많은 정교한 기술을 사용하여 최적의 실행 계획을 결정하며, 이러한 계획을 빠르고 효율적으로 실행할 수 있는 새로운 옵션이 많이 있습니다. 이러한 쿼리 기능을 다른 상업적으로 사용가능한 데이터베이스 서버에서 사용할 수 있기는 하지만, 어떠한 기능도 쉽게 사용할 수 있거나 운영 체제의 Microsoft Windows 제품에 잘 통합되지 않습니다.

Microsoft SQL Server에 대한 더 자세한 내용는 SQL Server 웹 사이트인 http://www.microsoft.com/sql/을 참조하십시오.



profile