KR20030047889A - 데이터베이스 질의를 자동으로 생성하는 시스템 및 방법 - Google Patents

데이터베이스 질의를 자동으로 생성하는 시스템 및 방법 Download PDF

Info

Publication number
KR20030047889A
KR20030047889A KR1020027016062A KR20027016062A KR20030047889A KR 20030047889 A KR20030047889 A KR 20030047889A KR 1020027016062 A KR1020027016062 A KR 1020027016062A KR 20027016062 A KR20027016062 A KR 20027016062A KR 20030047889 A KR20030047889 A KR 20030047889A
Authority
KR
South Korea
Prior art keywords
seq
emp
select
database query
date
Prior art date
Application number
KR1020027016062A
Other languages
English (en)
Inventor
에드워드 코스키우스코
메논 스리쿠마
형-병 보
존 빈센트
토마스 워링
조이스 라우
Original Assignee
컴퓨터 어소시에이츠 싱크, 인코포레이티드
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by 컴퓨터 어소시에이츠 싱크, 인코포레이티드 filed Critical 컴퓨터 어소시에이츠 싱크, 인코포레이티드
Publication of KR20030047889A publication Critical patent/KR20030047889A/ko

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/24Querying
    • G06F16/245Query processing
    • G06F16/2453Query optimisation
    • G06F16/24534Query rewriting; Transformation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/21Design, administration or maintenance of databases
    • G06F16/217Database tuning

Landscapes

  • Engineering & Computer Science (AREA)
  • Databases & Information Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Data Mining & Analysis (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Computational Linguistics (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

데이터베이스 질의를 조정하는 방법은, 데이터베이스 질의를 선택하는 단계; 선택된 데이터베이스 질의를 파싱하여, 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하는 단계; 복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택하는 단계; 결정된 관계와 선택된 최적화 모드에 기초하여 선택된 데이터베이스 질의 중 적어도 한 부분을 수정함으로써 선택된 데이터베이스 질의를 조정하는 단계; 및 수정된 데이터베이스 질의를 표시하는 단계를 포함한다.

Description

데이터베이스 질의를 자동으로 생성하는 시스템 및 방법{SYSTEM AND METHOD FOR AUTOMATICALLY GENERATING DATABASE QUERIES}
<관련 출원에 대한 참고>
본 출원은 2000년 5월 26일에 출원한 미국특허 가출원 제60/207,379호에 기초한 것이며, 그 내용 전체가 본 명세서에는 참조로서 인용되었다.
구조화 질의어(Structured Query Language : SQL)는 데이터베이스와 연동하는 ANSI 표준어이다. SQL은 사용자가 데이터베이스로부터 데이터를 검색하기 위해서 데이터베이스 내의 많은 여러 세트의 레코드(테이블)로부터의 정보를 결합할 수 있게 하는 것이다. 그러나, SQL의 능력도 일부 단점이 있다. 예를 들면, 사용자는 SQL 질의 중의 여러 테이블들을 결합하는 것이 가능한데, 이는 데이터베이스 엔진이 해결할 수 없는 질의를 생성하거나, 상당한 양의 시스템 자원을 사용할 수도 있다.
데이터베이스 시스템은 종종 성능 조정 시스템 또는 방법을 포함한다. 예를 들면, 오라클 7은, 하나 이상의 리포트에 데이터베이스의 동작 상태를 요약하여,성능 조정을 돕는 데 사용될 수 있는 다양한 스크립트(예를 들면, UTILBSTAT 및 UTLESTAT)를 제공한다. 이러한 스크립트는, 시스템 전반의 데이터베이스 성능 통계의 스냅샷을 캡쳐하고, 오퍼레이터가 데이터베이스의 성능을 최적화할 수 있도록 도울 수 있는 리포트를 생성하는 데 유용한 한 세트의 SQL 스크립트이다. 데이터베이스 오퍼레이터는 데이터베이스 성능의 미세 조정과 데이터베이스의 예방 관리를 위해 리포트를 이용할 수 있다. 리포트는, 예를 들면 라이브러리 캐시, 딕셔너리 캐시, 래치 사용, 파일 I/O, 및 롤백(rollback) 통계를 포함하는 데이터베이스 메모리 대상에 관한 정보를 포함할 수 있다.
기존 시스템의 문제점은 최적의 실행 계획을 입안하는 데 드는 시간을 종종 한정한다는 점이다. 또한, 그 대상 통계가 일단 주어지면, 식견이 있는 사용자는 대상 통계에 의해 표현된 것보다는 데이터에 대해 더 식견이 있을 수 있다. 기존 시스템은 종종 사용자의 지식을 이용하지 않는다. 또한, 통계가 적절하게 제공되고 분석될 때는 유용할 수 있지만, 대상이 분석되지 않았다면 통계는 전혀 존재하지 않거나, 통계는 오래된 것일 수 있다. 데이터의 분포에 대한 식견을 제공할 명확한 통계가 특정한 때에 존재하지 않을 수 있다. 한편, 사용자는 그렇지 않으면 사용 가능하지 않을 수 있는 데이터베이스 질의를 조정하는 데 유용할 수 있는 직접 지식을 갖고 있을 수 있다. 예를 들면, 시스템이 정상적으로 완전히 이용될지라도, 사용자는 복수의 CPU 등의 많은 자원이 사용 가능할 때 질의가 동시에 실행될 것이라는 것을 알고 있을 수 있다. 이러한 정보는 데이터베이스 질의 조정 프로세스 동안 매우 유용한 것으로 판명될 수 있다.
본 발명은 데이터베이스에 관한 것으로서, 보다 구체적으로는 데이터베이스 질의(database query)를 자동으로 생성하는 시스템 및 방법에 관한 것이다.
도 1은 일 실시예에 따른 데이터베이스 질의 조정 프로세스를 도시하는 블럭도.
도 2는 SQL 문장을 포함하는 대화 표시를 도시하는 도면.
도 3은 최적화 모드 선택 대화 표시를 도시하는 도면.
도 4는 프레퍼런스 창 표시를 도시하는 도면.
도 5는 SQL 점검 대화 표시를 도시하는 도면.
도 6은 결과 창 표시를 도시하는 도면.
도 7은 편집 또는 조정 창 표시를 도시하는 도면.
도 8은 상세 결과 창 표시를 도시하는 도면.
도 9는 본 발명의 시스템 및 방법이 적용될 수 있는 컴퓨터 시스템의 블럭도.
도 10 내지 도 13은 여러 SQL 문장들의 테이블에 대한 계층을 도시하는 도표도.
데이터베이스 질의를 조정하는 방법은, 데이터베이스 질의를 선택하는 단계; 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해 선택된 데이터베이스 질의를 파싱(parsing)하는 단계; 복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택하는 단계; 결정된 관계 및 선택된 최적화 모드에 기초하여 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써, 선택된 데이터베이스를 조정하는 단계; 및 수정된 데이터베이스 질의를 표시하는 단계를 포함한다.
파싱 단계는 데이터베이스 질의 내에서 토큰(token)을 결정하고, 토큰은 구획 문자(delimiter)에 의해 분리된 워드(word)이다. 복수의 사용 가능한 최적화 모드는 비용 기반 및 규칙 기반 모드를 포함할 수 있다. 비용 기반 모드는 First_Row 모드 및 All_Rows 모드를 포함할 수 있다. 본 발명은 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용을 결정하는 단계를 더 포함한다. 본 방법은, 선택된 데이터베이스 질의를 사용하는 데 관련되는 비용을, 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용과 비교하는 단계를 더 포함한다. 본 방법은 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절(clause) 중 적어도 하나에 의해 조인(join)된 적어도 하나의 부질의(subquery)를 포함하는지의 여부를 결정하기 위해 선택된 데이터베이스 질의를 파싱하는 단계를 더 포함한다. 본 방법은 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절 중 적어도 하나를 포함하는지의 여부에 기초하여 조정할 때 사용될 프레퍼런스(preference)를 선택하도록 사용자에게 프롬프트(prompt)하는 단계를 더 포함한다.
프레퍼런스는 NOT EXISTS 연산자로부터 NOT IN 연산자로의 변환과 선택된 데이터베이스 질의로부터 아웃터 조인(outer join)으로의 변환 중 적어도 하나의 변환을 사용자가 선택할 수 있게 하는 재작성(rewrite) 프레퍼런스를 포함할 수 있다. 프레퍼런스는 ALL 연산자에 의해 조인된 부질의를 조인 또는 아웃터 조인으로 변환하도록 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함할 수 있다. 프레퍼런스는 NOT IN 연산자에 의해 조인된 부질의를 변환하기 위해 NOT EXISTS 연산자와 아웃터 조인 중 적어도 하나를 사용할지의 여부를 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함할 수 있다.
데이터베이스 질의를 조정하기 위한 컴퓨터 실행 가능 코드를 포함하는 컴퓨터 저장 매체는, 사용자가 데이터베이스 질의를 선택할 수 있게 하는 컴퓨터 실행 가능 코드; 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해 선택된 데이터베이스 질의를 파싱하는 컴퓨터 실행 가능 코드; 사용자가 복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택할 수 있게 하는 컴퓨터 실행 가능 코드; 판정된 관계와 선택된 최적화 모드에 기초하여 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써, 선택된 데이터베이스 질의를 조정하는 컴퓨터 실행 가능 코드; 및 수정된 데이터베이스 질의를 표시하는 컴퓨터 실행 가능 코드를 포함한다.
데이터베이스 질의를 조정하기 위한 프로그램된 컴퓨터 시스템은, 사용자에게 적어도 하나의 데이터베이스 질의를 표시하기 위한 표시기; 사용자가, 표시된 데이터베이스 질의 중에서 한 데이터베이스 질의를 선택할 수 있게 하고, 복수의사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택할 수 있게 하는 사용자 입력; 및 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해서 선택된 데이터베이스 질의를 파싱하고, 결정된 관계 및 선택된 최적화 모드에 기초하여 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써, 선택된 데이터베이스 질의를 조정하기 위한 프로세서 - 수정된 데이터베이스 질의는 표시기를 통해 사용자에게 표시됨 - 를 포함한다.
도면에 도시된 본 개시의 양호한 실시예의 설명에 있어서, 명백히 할 목적으로 특정 용어가 사용된다. 그러나, 본 개시는 이와 같이 선택된 특정 용어에 한정되는 것으로 의도되지 않았으며, 각각의 특정 구성 요소는 유사한 방식으로 동작하는 모든 기술적 등가물을 포함한다는 것을 이해하여야 한다.
본 개시는 성능을 증가시키기 위해 데이터베이스 질의를 자동으로 조정하는 시스템 및 방법에 관한 것이다. 예를 들면, 본 시스템 및 방법은 최적의 실행 계획을 입안하기 위해 구조화 질의어(SQL) 문장을 조정할 수 있는 데이터베이스 관리 시스템(database management system : DBMS)의 형태일 수 있다. 일 특성으로서, 본 개시는 데이터베이스 구조의 문맥(context)에서 데이터베이스 질의를 분석하고, 그 질의를 수정 및/또는 재구성하여, DBMS 구조의 문맥 내에서 실행될 수 있는 시스템 및 방법에 관한 것이다. 또한, 본 개시의 시스템 및 방법은 질의에 의해 사용되는 DBMS 자원을 최소화하고 질의가 완성되는 것을 보장하기 위해 데이터베이스 관계형 구조를 이용할 수 있다.
이 결과를 달성하기 위한 한가지 방법은 SQL 문장을 SQL 문장의 수정 및/또는 재구성을 허용하는 고객(custom) 데이터 구조로 파싱하는 것이다. 예를 들면, 예컨대 FROM 절의 각 테이블은 참조 무결성(referential integrity)을 위해 점검되고, 예컨대 사용자 WHERE 조건과 비교될 수 있어, WHERE 조건은 올바른 아웃터 조인 규정에 대해 점검될 수 있다.
본 시스템은 SQL 문장을 파싱하고 각 토큰의 자취(track), 테이블이 조인된방식, 및 SQL 문장의 부분들 간의 관계를 유지한다. 토큰은 구획 문자에 의해 분리된 SQL 문장 내의 임의의 워드일 수 있다. 테이블 열 명칭을 나타내는 토큰은 SQL 문장 내에 존재하는 조인 및 다른 관계를 식별하기 위해 사용될 수 있다. 본 시스템 및 방법은, 예를 들면 조인 순서를 변경할 수 있고, 최상의 성능을 위해 SQL 문장을 조정하도록 부질의를 이동할 수 있다. 본 시스템 및 방법은 메인프레임, 개인용 컴퓨터(PC), 휴대 컴퓨터 등과 같은 컴퓨터 시스템 상에서 실행하는 소프트웨어 애플리케이션의 형태로 구현될 수 있다. 컴퓨터 시스템은 데이터베이스와 링크될 수 있다. 링크는, 예를 들면 직접 하드 와이어 또는 무선 연결과 같은 직접 링크, 근거리 통신망과 같은 망 연결, 또는 인터넷을 통할 수 있다.
본 시스템 및 방법을 구현할 수 있는 컴퓨터 시스템의 예는 도 9에 도시되어 있다. 일반적으로 시스템(200)으로 지칭되는 컴퓨터 시스템은 중앙처리부(CPU)(202), 메모리(204), 프린터 인터페이스(206), 표시부(208), LAN(local area network) 데이터 전송 제어기(210), LAN 인터페이스(212), 망 제어기(214), 내부 버스(216), 및 키보드, 마우스 등과 같은 하나 이상의 입력 장치(218)를 포함할 수 있다. 도시된 것처럼, 시스템(200)은 데이터베이스(220)에 링크(222)를 통해 연결될 수 있다.
도 1은 성능 증가를 위해 SQL 문장을 조정하기 위한 본 개시의 일 실시예에 따른 프로세스를 도시한다. 먼저, 사용자는 조정하기를 희망하는 SQL 문장을 선택한다(단계 S2). 예를 들면, 표시부(208)에 표시된 SQL 편집 창으로부터, 사용자는 SQL 문장의 처음에 커서를 위치시켜 마우스의 왼쪽 버튼을 클릭하고 SQL 문장의 끝까지 스크롤 다운한 다음 마우스를 해제함으로써 조정하기를 희망하는 SQL 문장을 강조한다. 이는 SQL 문장을 강조할 것이다. 그리고, 사용자는, 예를 들면 적절한 버튼을 클릭하여, 도구 메뉴(도시되지 않음)로부터 SQL 조정기 선택사항을 선택할 수 있다.
그리고, 도 2에 도시된 것처럼, 이 강조된 SQL 문장은 SQL 조정기 창(1)에 표시된다(단계 S4). 그리고, 사용자는 표시된 SQL 문장(2)이 자신이 조정하기 희망하는 SQL 문장인지를 확인하기 위해서 이를 다시 본다. 그리고, 사용자는 이전 버튼(3), 다음 버튼(4), 종료 버튼(5), 또는 취소 버튼(6)을 클릭하는 선택사항을 갖는다. 이전 버튼(3)은 이전 창으로 돌아가서, 사용자가 다른 SQL 문장을 선택하게 허용한다. 취소 버튼(6)은 표시된 SQL 문장(2)에 어떠한 변경도 하지 않고 SQL 조정기 창(1)을 빠져나온다. 다음 버튼(4)은 다음 창(도 3에 도시됨)으로 이동하여, 사용자가 이하 설명될 최적화 모드 설정을 선택할 수 있게 한다. 최종 버튼(5)은 현재 최적화 모드 설정을 사용하여 SQL 조정 프로세스를 실행한다.
본 시스템은 복수의 최적화 모드를 이용하여 동작할 수 있고, 복수의 다른 재작성 프레퍼런스를 이용할 수 있다. 다음 버튼(4)이 사용자에 의해 클릭된 후, 도 3에 도시된 것처럼, 본 시스템은 SQL 문장을 파싱하고(단계 S6), 최적화 모드 선택 창(11)을 표시한다. SQL 문장은, 예를 들면 어느 연산자, 함수 등이 문장에 존재하는지를 판정하기 위해 점검된다. 또한, 본 시스템은 SQL 문장 내의 부질의가 NOT EXISTS, NOT IN, 또는 ALL 절에 의해 조인되어 있는지를 판정하기 위해 점검한다. 또한, 본 시스템은 테이블 통계를 점검한다. 예를 들면, 테이블의ANALYZE 명령을 실행할 때 오라클과 같은 시스템에 의해 생성된 테이블 통계가 점검된다. 이 테이블 통계는 로우(row) 수(NUM_ROW), 상위 워터마크 아래의 데이터 블럭의 수(예를 들면, 현재 데이터를 포함하는지 또는 비어있는지에 상관없이 데이터를 수신하도록 포맷되어진 데이터 블럭의 수)(BLOCK), 한번도 사용되지 않은 테이블에 배치된 데이터 블럭의 수(EMPTY_BLOCKS), 바이트로 나타낸 각 데이터 블럭의 평균 사용 가능한 빈 공간(AVG_SPACE), 연결된 로우(chained row)의 수(CHAIN_COUNT), 및 로우의 오버헤드를 포함하는 평균 로우 길이(AVG_ROW_LEN)를 포함한다.
충분한 정보가 있으면(예컨대, 관련된 테이블에 대한 통계가 있으면), 시스템은 자동적으로 최적화 모드를 선택한다. 선택된 최적화 모드는 라디오 버튼(7-9)에 의해 표시된다. 예를 들면, 관련된 테이블에 통계가 있으면 좋은 결과를 내놓을 것이므로 비용 기반 최적화(First_Row 또는 All_Rows) 모드가 자동으로 선택될 수 있다. 단계 S8에서, 시스템이 자동으로 최적화 모드를 선택하기 위한 테이블 통계의 정보가 불충분하거나, 사용자가 시스템에 의해 자동으로 생성된 최적화 모드 설정을 변경하기 희망하면, 사용자는 도 3에 도시된 것과 같은 최적화 모드 선택 창(11)의 라디오 버튼(7-9) 중의 하나를 클릭하여 수동으로 선택할 수 있다. 또한, 사용자는 프레퍼런스 버튼(10)을 클릭함으로써, 이하 상세하게 설명될 것처럼 창(11)으로부터 재작성 프레퍼런스 설정을 수정할 수 있다.
하나의 비용 기반 최적화 모드는 All_Rows 모드로서 지칭된다. All_Rows 모드는 SQL 문장에서 참조되는 테이블 중 적어도 하나에 통계가 있으면 시스템에 의해 디폴트로서 자동으로 선택된다. All_Rows 모드는 배치 프로세싱에 대해 신속한 쓰루풋(throughput)을 제공한다. 그리고, 사용자는 SQL 문장이 집합 연산자(예를 들면, 합집합, 교집합, 차집합, 전체집합), GROUP BY 절, FOR UPDATE 절, 애그리게이트 함수(aggregate function), 또는 DISTINCT 연산자를 포함하지 않으면, 라디오 버튼(8)을 클릭하여 First_Row 모드를 선택하는 선택사항을 갖는다. SQL 문장이 집합 연산자(예를 들면, 합집합, 교집합, 차집합, 전체집합), GROUP BY 절, FOR UPDATE 절, 애그리게이트 함수, 또는 DISTINCT 연산자를 포함하면, 사용자는 First_Row 모드를 선택하기 위한 선택사항이 주어지지 않을 것이다. All_Rows 모드는 라디오 버튼(7)을 클릭하여 사용자에 의해 수동적으로 선택될 수도 있다.
First_Row 모드는 시스템이 세션을 위해 사용할 최적화 모드를 달리 판정하지 못할 때 자동으로 시스템에 의해 선택될 수 있다. First_Row 모드는 라인 프로세싱에 대해 빠른 응답 시간이 희망될 때 수동으로 선택될 수 있다.
다른 모드는 규칙 기반 모드라 지칭된다. 규칙 기반 모드는 통계가 어떠한 참조 테이블에도 존재하기 않으면 자동으로 시스템에 의해 선택된다. 규칙 기반 모드는 라디오 버튼(9)을 클릭하여 수동으로 선택될 수 있다.
SQL 문장이 NOT EXISTS, NOT IN, 또는 ALL 절에 의해 조인된 부질의를 포함하였다고 파싱 프로세스 동안 판정되면, 프레퍼런스 버튼(10)은 창(11)에서 활성화된다(도 3). 프레퍼런스 버튼(10)을 클릭하면 사용자는 NOT IN 연산자, NOT EXISTS 연산자, 및 ALL 연산자에 의해 조인된 부질의를 재작성하는 데 사용될 재작성 프레퍼런스를 규정할 수 있게 된다.
예를 들면, NOT EXISTS 연산자를 위한 재작성 프레퍼런스는 사용자가 NOT EXISTS 연산자의 NOT IN 연산자로의 변환 및/또는 문장의 아웃터 조인으로의 변환을 선택할 수 있게 규정될 수 있다. ALL 연산자에 대한 재작성 프레퍼런스는 규정될 수 있으며, 이는 사용자가 문장의 조인 또는 아웃터 조인으로의 변환을 선택할 수 있게 한다. NOT IN 연산자에 대한 재작성 프레퍼런스는 NOT IN 연산자의 NOT EXISTS로의 변환 또는 문장의 아웃터 조인으로의 변환을 사용자가 선택할 수 있게 규정될 수 있다.
프레퍼런스는 주위 인터페이스 컬럼(column)이 NOT NULL로 정의되는 인스턴스(instance)로의 변환을 제한하는 선택사항을 선택함으로써 재작성하도록 사용자에 의해 더 정의될 수 있다. 또한, 사용자는, 본 시스템이 항상 변환하며 필요하면 문장에 IS NOT NULL 기준(criteria)을 추가한다는 것을 규정할 수도 있다.
프레퍼런스 버튼(10)이 사용자에 의해 클릭될 때, 도 4에 도시된 프레퍼런스 창(50)이 표시된다. 그리고, SQL 조정기 프레퍼런스 페이지(52)는 조정기 탭(51)을 클릭하여 표시될 수 있다. 이 창의 선택사항은 사용자가 ALL, NOT IN, 및 NOT EXISTS 연산자에 의해 조인된 부질의에 대해 상술된 것처럼 재작성 프레퍼런스를 설정할 수 있게 한다.
도 4에 도시된 예에서, NOT EXISTS 연산자에 대한 재작성 프레퍼런스를 설정하기 위해서, 사용자는 풀다운 메뉴(53)로부터 NOT EXISTS 연산자를 선택한다. 이는 NOT EXISTS 연산자에 대해 사용 가능한 선택사항의 목록을 표시한다. 예를 들면, 사용자는 "NOT EXISTS 연산자를 통해 조인된 부질의를 NOT IN으로 변환"(선택박스 53) 및 "NOT EXISTS 연산자를 통해 조인된 부질의를 아웃터 조인으로 변환"(선택 박스 56)인 선택사항을 위한 적절한 선택 박스를 선택 또는 해제하여 NOT EXISTS 연산자에 의해 조인된 부질의를 변환하기 위해서 NOT IN 및/또는 아웃터 조인을 본 시스템이 사용할 수 있게 되는지를 규정한다.
"NOT EXISTS 연산자를 통해 조인된 부질의를 NOT IN으로 변환"(선택 박스 53)가 선택되면, 선택사항 박스(57 및 58)는 활성화된다. 선택 박스(57)는 사용자가 "아웃터 질의의 조인된 컬럼에 대한 NOT NULL 조건 점검" 선택사항을 선택할 수 있게 하고, 선택사항 박스(58)는 사용자가 "부질의의 조인된 컬럼에 대한 NOT NULL 조건 점검" 선택사항을 선택할 수 있게 허용한다. 사용자는 선택 박스(59 및 60)를 각각 선택 또는 해제하여 이 선택사항의 하나 또는 모두를 선택할 수 있다. 그리고, 변환 선택사항은 각각의 선택된 선택사항 박스에 대해 활성화된다. 예를 들면, "컬럼이 NOT NULL로서 정의되었을 때만 변환"은 라디오 버튼(61 및 63)을 각각 클릭하여 아웃터 질의 및 부질의에 대해 선택될 수 있고, "항상 변환하고 필요하면 "IS NOT NULL"을 추가"는 라디오 버튼(62 및 64)을 각각 클릭하여 선택될 수 있다. 그리고, 규정된 프레퍼런스를 저장하고 프레퍼런스 창을 빠져 나오기 위해 사용자는 "OK" 버튼(54)을 클릭할 수 있다. 취소 버튼(66)의 선택은 프레퍼런스에 생성된 어떠한 변경도 저장하지 않고 창(52)을 빠져 나온다. 도움말 버튼(65)의 선택은 도움말 메뉴를 사용자에게 표시한다.
유사한 방식으로, ALL 연산자에 대한 재작성 프레퍼런스를 설정하기 위해서, 사용자는 선택사항의 목록을 표시하기 위해 풀다운 메뉴(53)로부터 "ALL 연산자"를선택한다. 그리고, 사용자는 "ALL 연산자를 통해 조인된 부질의를 조인 또는 아웃터 조인으로 변환" 선택사항을 선택 또는 해제하여 본 시스템이 ALL 연산자에 의해 조인된 부질의를 조인 또는 아웃터 조인으로 변환하게 할 수 있는지를 규정하기 위한 선택사항이 주어질 것이다.
사용자가 이 선택사항을 선택하면, 사용자는 "아웃터 질의의 조인된 컬럼에 대한 NOT NULL 조건을 점검" 및 "부질의의 조인된 컬럼에 대한 NOT NULL 조건을 점검"을 위한 선택사항이 주어질 것이다. 그리고, 사용자는 이 선택사항 중의 하나 또는 둘을 선택할 수 있다. 선택된 이러한 선택사항 중의 각각에 대해, 사용자는 두 가지 선택사항 "컬럼이 NOT NULL로서 정의될 때만 변환" 및 "항상 변환하고 필요하면 "IS NOT NULL"을 추가"가 주어진다.
사용자는 규정된 프레퍼런스를 저장하고 프레퍼런스 창을 빠져 나오기 위해서 "OK" 버튼을 클릭할 수 있다.
NOT IN 연산자에 대한 재작성 프레퍼런스를 설정하기 위해서, 사용자는 선택사항의 목록을 표시하기 위해서 풀다운 메뉴(53)로부터 NOT IN 연산자를 선택한다. 그리고, 사용자는 본 시스템이 "NOT IN 연산자를 통해 조인된 부질의를 NOT EXISTS로 변환" 및 "NOT IN 연산자를 통해 조인된 부질의를 아웃터 조인으로 변환" 선택사항을 선택 또는 해제함으로써 NOT EXISTS 연산자 및/또는 아웃터 조인을 NOT IN 연산자에 의해 조인된 부질의를 변환하기 위해 사용할 수 있는지를 규정할 수 있다.
선택된 각각의 선택사항에 대해, 사용자에게는, 조인된 컬럼에 대해 NOTNULL 조건을 점검하고 부질의의 조인된 컬럼에 대한 NOT NULL 조건을 점검하도록 선택사항이 주어진다. 사용자는 이 선택사항 중의 하나 또는 둘을 선택할 수 있다. 변환 선택사항은 각각의 선택된 선택사항에 대해 활성화된다. 즉, 사용자는 컬럼이 NOT NULL로서 정의될 때만 변환하거나 항상 변환하고 필요하면 "IS NOT NULL"을 추가하기 위한 선택사항이 주어진다. 그러므로, 사용자는 아웃터 질의 및/또는 부질의에 대해 조인된 컬럼에 대한 변환 선택사항을 선택할 수 있다. 사용자는 규정된 프레퍼런스를 저장하고 프레퍼런스 창을 빠져 나오기 위해서 "OK" 버튼(54)을 클릭한다. 프레퍼런스 창을 빠져 나온 후, 표시부는 최적화 모드 선택 창으로 돌아간다(도 3). 단계 S8이 완료되고 사용자가 최적화 모드 및 프레퍼런스 선택을 만족하면, 다음 버튼(8)을 클릭함으로써 프로세스가 계속될 수 있다.
단계 S10에서, 본 시스템은 참조 무결성, 아웃터 조인, 및/또는 NULL 로직(logic) 문제에 대해 SQL 문장을 점검한다. 에러 또는 비효율이 발견되면, 문제를 해결하기 위해 SQL 문장을 변경시키기 위한 특정 제안이 표시된다. 예를 들면, 제안은 비유효(invalid)한 결과 세트를 야기할 수 있는 비유효 아웃터 조인에 대해 표시될 수 있다. 또한, 제안은 비유효한 결과 세트, HAVING 절의 오사용, 카르테시안 프로덕트(cartesian product), 보다 나은 인덱스 이용을 위한 조인 기준의 표현, 보다 나은 인덱스 이용을 위한 넌조인(non-join) 기준의 표현, 및 인덱스되지 않은 외부 키 등을 야기하는 NULL 로직 문제에 대해 표시될 수 있다.
단계 S12에서, 도 5에 도시된 SQL 점검 창(70)이 사용자에게 표시된다. 창 일부(73)는 문장의 각각의 부질의의 도해를 표시한다. SQL 문장의 각 테이블은 테이블 명칭과 애일리어스(alias)를 포함하는 헤더를 갖는 박스로서 표시된다. 주 키, 외부 키, 및 고유 키도 각 테이블에 표시된다.
테이블 사이의 녹색선은 올바른 조인을 나타낸다. 적색선이 테이블을 연결하면, 조인은 (참조 무결성 손상 또는 비적절한 아웃터 조인과 같은) 에러를 포함한다. 청색선이 테이블을 연결하면, 조인은 참조 무결성의 부재로 인해 비효율적이다.
SQL 문장에 제안된 정정은 창 일부(71)에 표시된다. SQL 점검 창(70)은 임의의 창 일부에 포함된 모든 정보를 보여주도록 사용자에 의해 희망된 대로 크기 조정될 수 있다.
"다음 SQL 모듈" 버튼(72) 및 "이전 SQL 모듈" 버튼(74)을 클릭하여 SQL 문장의 각각의 부질의를 청색으로 강조하고 강조된 부질의의 관련 도해만을 표시한다.
그리고, 사용자는 원래 문장 또는 경정된 문장 중 어느 SQL 문장을 조정할지를 판단할 수 있다. 예를 들면, "원래 SQL 조정" 버튼(76)을 클릭하여 SQL 점검 창(70)의 버튼에서 필드(75)에 표시된 원래 SQL 문장을 조정한다. "경정된 SQL 조정" 버튼(78)을 클릭하여 SQL 창 점검(71)의 우측의 필드에 표시된 제안된 정정을 제공하고 정정된 SQL 문장을 조정한다.
단계 S16에서, 선택된 SQL 문장은 문장을 최적화하기 위해서 하나 이상의 단계를 수행하여 조정된다. 예를 들면, 본 시스템은 조인 기준의 이행성의(transitive) 변경을 생성할 수 있고, 모든 부질의 변환을 결정할 수 있으며, 필요하면 넌조인 기준의 이행성을 결정할 수 있고, 조인 순서를 결정할 수 있다. 본 시스템은 복수의 변환된 SQL 문장을 생성할 수 있다. 본 시스템은 변환된 SQL 문장의 어느 것이 가장 좋은 성능을 갖는지를 판정하고, 이에 따라 결과 SQL 문장을 소팅(sorting)할 수 있다.
SQL 문장을 조정 또는 변환할 때, 본 시스템은 주위 질의의 컬럼이 동일 테이블에 속하는지와 이행성의 변경을 생성하는지를 알아보기 위해서 필요하면 점검할 수 있다. 동일한 테이블에 속하지 않으면, 본 시스템은 조인 기준 중 어느 것이 부질의를 인터페이스하는 컬럼을 참조하는지를 점검하고 등가 컬럼을 식별한다. 본 시스템은 부질의를 인터페이스하는 각 컬럼에 대해 이를 수행한 다음에, 모든 컬럼이 동일한 테이블에 속하는 세트를 탐색하기 위한 시도에서 등가 컬럼의 치환을 행하기 위해서 이행성을 이용한다. 본 시스템은 NOT IN 연산자를 통해 조인된 비상관적(non-correlated) 부질의 및 NOT IN, NOT EXISTS, 또는 ALL 연산자와 인터페이스되는 상관된(correlated) 부질의에 이행성의 변경을 생성할 수 있다.
또한, 본 시스템은 각 부질의를 평가하고 각 변환에 순위를 할당하여 SQL 구문(syntax)에 수행될 수 있는 모든 부질의 변환을 판정할 수 있다. 변환은 강제적(항상 또는 전혀 안함) 또는 선택적일 수 있다. 그리고, 이 정보는 다양한 대체(alternative) SQL 버전을 생성하는 데 사용된다. 예를 들면, SQL 문장이 4개의 부질의를 포함한다면, 본 시스템은 가능한 대체 SQL 문장을 생성하기 위해서, 부질의 "항상 변환"은 없고, 하나의 "전혀 변환하지 않음", 및 3개의 "선택적"을 순위화할 수 있다.
즉, 변환의 유형은 변환이 항상 수행되어야 하는지, 전혀 수행되어야 하지 않는지, 선택적으로 수행되어야 하는지를 결정한다. 예를 들면, 변환이 수행되는 경우에 최적화기(optimizer)가 보다 좋은 계획을 사용한다면 일부 변환은 바람직할 수 있다. 이 경우에, 변환은 항상 수행되어야 한다. 따라서, 변환에는 최고의 순위가 할당될 것이다. 변환이 수행되는 경우에 최적화기가 덜 효율적인 계획을 사용한다면 일부 변환은 바람직하지 않을 수 있다. 이 경우에, 변환은 수행되어서는 안 된다. 따라서, 변환은 최하 순위가 할당될 것이다. 일부 변환은 다른 요인에도 의존할 것이므로, 보다 좋은 최적 계획이 선택되게 하거나 되지 않게 할 수 있다. 이 경우에, 변환은 선택적으로 수행될 수 있다. 따라서, 변환은 중간 순위가 할당될 것이다.
부질의 변환을 수행한 후, 본 시스템은 서로 대체될 수 있는 넌조인 기준의 등가 컬럼을 식별하고 대체를 한다. 이로써 본 시스템은 (예를 들면, 오라클과 같은) 데이터베이스가 연쇄(concatenated) 키 인덱스를 이용할 수 있도록 SQL 문장을 재작성하는 것이 가능하게 된다.
예를 들면, 이하의 SQL 문장에서, DEPENDENTS라는 부질의에 대한 e.emp_seq 기준은 a.emp_seq 또는 temp_seq에 인터페이스될 수 있다.
SELECT * FROM employees e, assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND e.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = 'SPOUSE')
후술되는 바와 같은 e.emp_seq의 a.emp_seq로의 스위칭(라인 5)은 데이터베이스가 ASSIGNMENTS에 대한 연쇄 키 인덱스를 사용할 수 있게 한다.
SELECT * FROM employees e, assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND a.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = 'SPOUSE')
컬럼을 등가로 하면서 상등(equality) 조인 기준이 존재할 때 다양한 컬럼이 다른 컬럼을 대체할 수 있다. 그러나, 본 시스템은 조인 기준에 AND된 넌조인 기준에 대해 이행성을 사용할 수도 있다. 넌조인 기준이 조인 기준에 OR된다면, 그로 인한 이행성은 사용되어서는 안 된다.
복수의 컬럼 피연산자(operand)가 이행성이 있으면, 본 시스템은 컬럼을 피연산자에 추가하고 선택 목록에 해당 컬럼을 복사한다. 모든 복수 컬럼 이행성은 원래의 문장을 제외하고 각각의 변환을 위해 사용된다. 피연산자가 아웃터 조인된 기준을 통해 다른 컬럼과 등가이면, 등가 컬럼이 사용될 수 없다.
FROM 절이 GROUP BY 구문 또는 애그리게이트를 갖지 않는 네스티드(nested) 선택 문장을 갖고 주질의가 주질의와 네스티드 선택 사이의 조인 컬럼 중의 하나를참조하는 넌조인 기준을 갖는다면, 본 시스템은 원본을 포함하여 모든 SQL 문장 복사본에 네스티드 선택 문장의 넌조인 기준을 복사한다.
본 시스템은 조인 순서를 결정하기 위해서, 순서화된 힌트를 사용할 수 있다. 순서화된 힌트는 최적화기가 테이블을 SQL 문장의 FROM 절에서 나타나는 순서로 조인하게끔 한다. 이는 작성될 SQL 문장이 FROM 절에서 참조된 테이블을 특정 순서로 조인하게 허용한다. 먼저, 본 시스템은 SQL 문장을 순서화된 힌트없이 시험한다. 그리고, 본 시스템은 특정 조인 순서를 강제하기 위해서 다른 드라이빙 테이블, 예를 들면 네스티드 루프 조인 동작의 부모(parent) 테이블인 드라이빙 테이블을 갖는 순서화된 힌트를 사용하여 추가적인 치환(permutation)을 생성한다. 드라이빙 테이블로부터의 각 로우는 조인 동작을 완료하기 위해 조인된 테이블에서 일치하는 로우를 탐색하기 위해 사용될 수 있다.
변환된 SQL 문장의 디폴트 조인이 원래 SQL 문장보다 좋은 비용/로우 값을 가지면, 순서화된 힌트는 디폴트 조인 순서를 사용한 초기 변환보다 효율적인 계획이지만 높은 비용/로우를 생성하기 쉬울 것이다. 본 시스템은 가능한 가장 좋은 해결책으로서 순서화된 변환을 표시할 수 있다.
각각의 생성된 대체 SQL 문장 중에서 가장 좋은 성능을 판정하기 위해서, 본 시스템은 원래 SQL 및 재작성 프로세스에 의해 생성된 SQL 문장 각각에 대한 비용 통계를 생성한다. 비용은 SQL과 관련된 계획을 생성한 후 판정된다. 예를 들면, 최적화기가 SQL 문장을 실행하기 위해 사용하는 계획을 생성하는 데 오라클의 EXPLAIN PLAN 문장이 사용될 수 있다. EXPALIN PLAN 문장은, 최적화기가 SQL 문장을 실행하는 데 사용하기 위해 계획하는 단계를 기술할 실행 계획을 얻기 위해서 SQL 문장에서 실행될 수 있다. 또한, 오라클은 계획의 각 단계에 대한 수(예를 들면, 비용)를 제공할 것이다. 비용은 계획의 단계를 실행하기 위해 사용하는 상대적인 숫자이다. 비용은 계획을 위한 총비용에 도달하기 위한 계획의 모든 단계에 대해 합계될 수 있다. 본 시스템은 SQL 문장의 각각에 대해 비용/로우 값을 생성하기 위해서, 데이터베이스에 의해 산출된 비용을 로우의 수로 나눌 수 있다. 또한, 비용은 계획에 의해 요구되는 논리적 판독의 수에 의해 판정될 수 있다. 비용을 판정한 후, 본 시스템은 증가하는 순서로(최저 비용으로부터 최고 비용으로) SQL 문장을 소팅한다.
단계 S18에서, 본 시스템은 도 6에 도시된 것처럼 결과 대화 창(90)에 원래 SQL 문장 및 최저 비용을 갖는 SQL 문장을 표시한다. 원래의 SQL 문장은 창 일부(92)에 표시되고, 제안된 대체 SQL 문장은 창 일부(94)에 표시된다. 그리고, 사용자는 제안된 대체 SQL 문장을 원래 SQL 문장과 비교하고, 변경을 검사하며, 원래의 SQL 문장을 조정된 SQL 문장으로 대체하기를 원하는지를 선택할 수 있다.
SQL 대체 버튼(100)을 클릭하면 원래 SQL 문장은 창(94)에 도시된 제안된 대체 SQL 문장으로 대체된다. 본 시스템은 도 7에 도시된 것처럼 편집 또는 조정 창(104)에서 코멘트를 추가하고 조정된 SQL 문장을 표시한다. 도 7에 도시된 것처럼, 코멘트는 날짜 스탬프, 문장이 조정되었음을 표시하고 사용된 최적화 모드(본 예에서는 All_Rows)를 식별하는 정보를 포함한다. 이전 버튼(96)을 클릭하면 이전 창으로 돌아간다. 상세 버튼(98)을 클릭하면, 도 8에 도시된 것처럼 상세 결과창(106)을 연다. 조정된 SQL 문장이 창 일부(108)에 표시된다. 로우(110)는 원래 SQL 문장에 대한 비용 통계를 표시하고, 하나 이상의 로우(112)는 조정된 대체 SQL 문장에 대한 비용 통계를 표시한다. 통계는 SQL을 실행하는 데 필요한 시간량인 경과 시간(초)(114), SQL을 실행하는 데 필요한 초당 CPU 사이클의 수인 CPU 시간(116), SQL을 실행하는 데 필요한 논리적 판독의 수인 로그 판독(log read)(118), SQL을 실행하는 데 필요한 물리적 판독의 수인 물리적 판독(120), SQL이 리턴하는 로우의 수인 로우(122), 로우의 수로 나누어진 데이터베이스 비용인 비용/로우(124)를 포함할 수 있다.
상세 결과 창(106)은 사용자가 필요에 가장 적절한 SQL을 선택하는 데 일조하기 위해 각 문장에 대한 비용 통계를 볼 수 있게 한다. 또한, 사용자는 더 편집하기 위한 편집기 기능을 포함하는 시스템에서 조정된 문장을 여는 것을 선택할 수 있다.
SQL에 "바인드(bind)" 변수(variable)가 있으면, "바인드" 버튼(126)을 클릭하여 SQL 문장을 실행하기 전에 사용자가 변수에 대한 값을 규정할 수 있는 대화를 표시한다. "실행" 버튼(128)을 클릭하면, 선택된 문장에 대한 통계를 생성한다. "모두 실행" 버튼(130)을 클릭하면 나열된 SQL 문장 모두에 대한 통계를 생성한다. 사용자는 창에 현재 표시된 정보를 인쇄하기 위해서 "인쇄" 버튼(134)을 클릭할 수 있다. 사용자는 이후의 참조를 위한 텍스트 파일로서 이 창의 정보를 저장하기 위해서 "저장" 버튼(134)을 클릭할 수 있다. 사용자는 계획자 창에 코드를 표시하기 위해서 테이블의 대체 SQL 엔트리를 선택하고 "PAFO"(Plan analyzer for Oracle)버튼(138)을 클릭할 수 있다.
"SQL 대체" 버튼(140)을 클릭하면 원래 SQL을 조정된 SQL로 대체한다. "이전" 버튼(136)을 클릭하면 결과 창(90)으로 돌아간다(도 6). "취소" 버튼(144)을 클릭하면 원래 SQL을 변경하지 않고 본 시스템을 빠져 나온다.
이하의 설명은 SQL 문장을 조정하기 위해 본 시스템에 의해 사용된 개념의 일부는 물론, SQL 문장의 참조 부분 또는 속성에 대해 본 명세서에서 사용된 다양한 용어를 나열하고 설명한다. 이 용어들은 본 명세서에서 SQL 문장을 조정하기 위해 본 시스템에 의해 사용된 알고리즘을 설명하는 데 사용된다.
A. 브랜치 및 네스팅 레벨(Branch and Level of Nesting)
질의가 부질의일 때, 최상위(주질의)로부터 최하위까지의 경로가 "브랜치(branch)"이다. "네스팅 레벨"은 브랜치에서 부질의의 수이다. 주질의는 "레벨" = 1로 고려된다. 그 바로 아래의 부질의는 "레벨" = 2에 있다. 이하의 SQL을 고려하면서, 참조를 위해 라인 번호가 추가되었다.
1.SELECT * FROM employees
2.WHERE emp_seq IN
3.(SELECT emp_seq
4.FROM time_sheets t,
5.WHERE t.rpt_date = '01-MAY-98'
6.AND t.proj_seq =
7.(SELECT proj_seq FROM projects
8.WHERE name = 'EXPLAIN SQL: DEVELOPMENT'))
9.AND hiredate > SYSDATE - 10
브랜치는 주질의, LEVEL = 1(시작 라인 1)로부터 LEVEL = 2(시작 라인 3)까지 LEVEL = 3 최종 부질의(시작 라인 7)까지 연장된다. 이 예에서, 주질의는 부질의를 갖고 부질의는 다시 부질의를 가지므로 "네스팅 레벨"은 2이다. 이하 SQL 문장은 2개의 브랜치를 포함한다.
1.SELECT * FROM employees
2.WHERE emp_seq IN
3.(SELECT emp_seq
4.FROM time_sheets t
5.WHERE t.rpt_date = '01-MAY-98'
6.AND t.proj_seq =
7.(SELECT proj_seq FROM projects
8.WHERE name = 'EXPLAIN SQL: DEVELOPMENT'))
9.AND hiredate > SYSDATE - 10
10.AND emp_seq IN
11.(SELECT emp_seq FROM dependents
12.WHERE birthdate > '01-JAN-67')
이 SQL 문장에서 제1 브랜치는 이전 예와 동일하다. 그러나, 이 SQL 문장은 2개의 브랜치를 갖는다. 주질의(라인 1에서 시작)는 레벨 1이다. 레벨 2는 라인11에서 시작한다. 이 제2 브랜치는 1과 동일한 네스팅 레벨을 갖는다.
B. 최상 부모 불리언 연산자(Top-Most Parent Boolean Operator)
OR 연산이 WHERE 절에 있을 때, 부질의를 FROM 절로 머지(merge)하거나 이동(move)하기 전에 주의하여야 한다. OR가 부모 불리언 연산자이면, 머지 또는 이동은 일어나서는 안 된다. 이하 예는 이 점을 설명한다.
SQL 문장:
SELECT e.emp_seq FROM employees e
WHERE hiredate > SYSDATE - 155
OR emp_seq IN (SELECT emp_seq FROM assignments
WHERE proj_seq = 1)
OR 연산자를 고려하지 않았다면, 부질의는 다음과 같이 머지될 것이다.
SELECT e.emp_seq, x.emp_seq FROM employees e,
(SELECT emp_seq FROM assignments
WHERE proj_seq = 1) x
WHERE e.hiredate > SYSDATE - 155
OR e.emp_seq = x.emp_seq
그러나, 이제 조인은 부질의에 조인하는 로우가 없을 때 카르테시안 프로덕트가 될 것이다. 예를 들면, 기준 "e.emp_seq = x.emp_seq"이 FALSE로 판정되고 넌조인 기준이 TRUE로 판정되면, 부질의로부터의 로우는 상관없이 조인될 것이다. 그 특정 EMPLOYEES 로우에 대해, 넌조인 기준은 부질의의 어느 로우가 조인되는지에 상관없이 항상 TRUE로 판정될 것이다. 이는 카르테시안 프로덕트를 생성한다.
이하의 예는 NOT이 기준 앞에 있을 때 문제가 보다 어려워질 수 있음을 설명한다.
예를 들면, SQL 문장:
SELECT e.emp_seq FROM employees e
WHERE NOT(hiredate > SYSDATE - 155
OR emp_seq IN (SELECT emp_seq FROM assignments
WHERE proj_seq = 1))
이 주어진다.
드모르강(DeMorgan)의 법칙을 사용하면, NOT은 포함되어 있는 불리언 및 관계형 연산자를 반전시킨다. 그러나, 본 시스템은 드모르강의 법칙을 사용하여 NOT 연산자를 제거할 수 있어서, 이하의 SQL을 얻는다.
SELECT e.emp_seq FROM employees e
WHERE hiredate <= SYSDATE - 155
ANDemp_seqNOTIN (SELECT emp_seq FROM assignments
WHERE proj_seq = 1)
반전된 불리언 및 관계형 연산자는 밑줄이 그어져 있다. 반전을 먼저 하여 프로세스를 간단하게 한다.
C. 다중 SQL 모듈로의 상관(Correlated to Multiple SQL Modules)
상관된 부질의는 이하의 예에 나타나 있는 것처럼 하나 이상의 SQL 모듈에상관될 수 있다.
1.SELECT* FROM employees e
2.WHERE EXISTS
3.(SELECT null FROM assignments a
4.WHERE a.emp_seq = e.emp_seq
5.AND EXISTS
6.(SELECT null FROM time_sheets t
7.WHERE t.emp_seq = e.emp_seq
8.AND t.proj_seq = a.proj_seq))
TIME_SHEETS(라인 6)의 부질의는 (라인 7을 통해) 주위 질의(ASSIGNMENT의) 및 (라인 8을 통해) EMPLOYEES의 주질의 모두에 상관된다.
D. 상관 기준(Correlation Criteria)
상술한 SQL 문장에서 라인 7 및 8의 기준은 "상관 기준"이라 지칭된다. 이 기준은 질의 외부의 참조("e.emp_seq" 또는 "a.proj_seq")가 부질의가 실행될 때 상수와 유사하다는 점에서 "조인 기준"이라기 보다는 "넌조인 기준"에 가깝다.
상관 기준은 상등 연산자를 이용하는 것을 확인하기 위해서 루틴에서 점검될 수 있다. 그러나, 이 방식으로 점검되어야 하는 상관 기준은 고유 인덱스를 포함하는 컬럼에 해당하는 것이라는 것을 알아야 한다. 예를 들면, 이하의 질의는 부질의에 2개의 상관 기준을 갖는다. 그러나, 고려되는 단 한 가지 점은 그것이 고유한 인덱스를 갖는 컬럼이므로 PROJ_SEQ에 대한 것이다.
SELECT * FROM assigimients a
WHERE EXISTS
(SELECT start_date FROM projects p
WHERE a.proj_seq = p.proj_seq
AND a.start_date < p.start_date)
E. 넌조인 기준(Non-Join Criteria)
SQL 문장에서, 이하 코드가 넌조인 기준을 참조할 때, 관계형 연산자가 "="이고 다른 피연산자가 상수 또는 부질의인 기준을 탐색한다. 부질의에 관한 가정은 사용자가 '='를 관계형 연산자로 규정하였으므로, 부질의는 상수를 의미하는 단일 로우에서 리턴되어야 한다는 것이다.
이하는 비유효한 WHERE 절의 예이다.
WHERE coll = 10 + col2
WHERE col1 > 10
이하는 유효한 WHERE 절의 예이다.
WHERE col1 = 10
WHERE col1 = (select co12 from tabl)
WHERE col1 = :Bind-Variable
F. 조인 기준(Join Criteria)
조인 기준이 이하 참조된다. 각 경우에 관계형 연산자는 "="이어야 하고 기준의 양측은 단일 컬럼 명칭이고 식이 아니어야 한다.
G. 부질의 인터페이스(Subquery Interface)
주위 질의와 부질의 사이의 인터페이스는 통상적으로 "IN", "=", "NOT EXISTS" 등과 같은 최소한 하나의 관계형 연산자"를 포함한다. EXISTS 및 NOT EXISTS 관계형 연산자를 제외한 모든 것에는 하나 이상의 컬럼이 앞에 있다. 연산자 앞에 있는 컬럼은 "인터페이스 컬럼"이라 지칭된다. 부질의의 해당 SELECT 목록의 컬럼은 "인터페이스 컬럼"이라 지칭된다. 이러한 2 가지 유형의 "인터페이스 컬럼"은 주위 질의 또는 부질의를 위한 인터페이스 컬럼인지에 따라 구분될 수 있다.
컬럼이 부질의 내의 오브젝트에 속하지 않고 부질의의 테이블에 속하는 임의의 컬럼과 상관되지 않는 것이 가능하다.
1.SELECT * FROM employees e
2.WHERE emp_seq IN
3.(SELECT emp_seq FROM assignments a
4.WHERE (e.hiredate, a.proj_seq) IN
5.(SELECT rpt_date, proj_seq FROM time-sheets t))
컬럼 "e.hiredate"(라인 4)는 부질의(ASSIGNMENT 테이블)에 속하지 않고 ASSIGNMENT의 모든 컬럼과 상관되지 않는다. 이 도큐먼트는 "외부적(foreign)"으로서 주위 질의의 컬럼을 지칭할 것이다. 컬럼이 외부적이면, 본 시스템은 비상관 부질의로 이를 머지하거나 이를 변환하려고 시도할 것이다. 그러나, 본 시스템은 그 부질의를 이동하려고 시도하지 않을 것이다.
H. 프레퍼런스(Preference)
널(null) 로직은 SQL 문장을 변환할 때 복수의 문제를 일으킬 수 있다. 일정 컬럼이 주위 질의에서 널이 가능하면, 변환될 때 다른 결과 세트가 나타날 수 있다. 프레퍼런스 면에서 적은 비용일 수 있지만, 변환은 이것이 발생하지 않는 것을 보장하도록 수정될 수 있다. 수정은 기준을 AND하는 것이고, 컬럼이 널이 될 수 없음(예를 들면, col IS NOT NULL)을 규정한다. 그 기준이 원래의 기준을 만족하는 각 로우에 대해 유효화되어야 하므로, 약간의 비용이 있을 것이다. 한편, 어떤 경우에 프레퍼런스는 오라클의 최적화기와 같은 최적화기가 이제 안티조인(anti-join)을 수행할 수 있기 때문에 개선할 것이다. 이 프레퍼런스는 이하 알고리즘에서 참조될 것이다.
I. 애일리어스(aliases)
부질의가 FROM 절로 머지 또는 이동될 때, 주위 질의의 기준은, 예를 들면 이하의 예를 참조하여 도시될 것처럼 애일리어스를 통해 완전히 식별되어야 한다.
1.SELECT * FROM employees
2.WHERE emp_seq IN
3.(SELECT emp_seq
4.FROM time_sheets t, projects p
5.WHERE t.rpt_date = '01-MAY-98'
6.AND t.proj_seq = p.proj_seq
7.AND p.stop_date IS NULL)
8.AND hiredate > SYSDATE - 10
이 예에서, 애일리어스는 EMPLOYEES에 대해 추가되어야 하고, 그 애일리어스는 그 테이블에 속한 모든 컬럼 앞에 있어야 한다. 또한, 부질의는 애일리어스가 주어져야 한다. EMPLOYEES에 대한 "e" 애일리어스를 추가하면 변환은 다음과 같이 될 것이다.
SELECT e.* FROM employees e,
(SELECT emp_seq
FROM time sheets t, projects p
WHERE t.rpt_date = '01-MAY-98'
AND t.proj_seq = p.proj_seq
AND p.stop_date IS NULL) x
WHERE e.emp_seq = x.emp_seq
AND e.hiredate > SYSDATE - 10
부질의가 애그리게이트를 포함하면, 이는 FROM 절로 이동되기 전에 애일리어스가 주어져야 한다. 예를 들면, 이하의 SQL 문장은 "max" 애그리게이트 함수를 부질의에 포함한다(라인 3).
1.SELECT * FROM sal_history
2.WHERE (emp_seq, effective_date) IN
3.(SELECT emp_seq, max(effective_date)
4.FROM sal_history
5.GROUP BY emp_seq)
SQL 문장은 다음과 같이 애그리게이트 "MAX(EFFECTIVE_DATE)"에 애일리어스를 주도록 변환되어야 한다.
SELECTs.* FROM sal_history s,
(SELECT emp_seq, max(effective_date) cl
FROM sal_history
GROUP BY emp_seq) x
WHERE s.emp_seq = x.emp_seq
AND s.effective_date = x.cl
문제는 사용자가 확실한 지식으로 고유한 세트를 리턴하기 위해 알려진 부질의를 플래그하도록 허용하는지로부터 발생한다.
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT null FROM projects p, assignments a
WHERE p.proj_seq = a.proj_seq
AND a.emp_seq = e.emp_seq
AND p.name = 'EXPLAIN_SQL')
SELECT * FROM employees e
WHERE e.emp_seq IN
(SELECT a.emp_seq FROM projects p, assignments a
WHERE p.proj_seq = a.proj_seq
AND p.name = 'EXPLAIN_SQL')
으로 변환되거나
SELECT e.* FROM employees e, projects p, assignments a
WHERE e.emp_seq = a.emp_seq
AND p.proj_seq = a.proj_seq
AND p.name = 'EXPLAIN_SQL'
으로 변환된다.
부질의의 저레벨 테이블은 PROJ_SEQ 및 EMP_SEQ에 PK를 갖기 때문에 두 경우가 가능하다. 이행성은 UNQ 인덱스도 갖는 NAME의 상등 때문에 PROJ_SEQ에 상등성이 있다고 말할 수 있게 한다. 그러므로, 부질의가 EMPLOYEES 로우마다 하나의 로우를 생성하기 위해서 보장되고, 이는 머지이 가능하다는 것을 의미한다.
본 시스템에 의해 사용된 용어 및 개념의 일부가 설명되었고, 이하 예는 SQL 문장을 변환하기 위해 본 시스템에 의해 사용될 수 있는 알고리즘을 설명하는 데 일조한다는 것을 주의하자. 예는 상관 및 비상관된 부질의에 대해 도시되고 그렇게 식별된다. 비상관된 부질의는 주질의에 상관되지 않은 부질의이다. 즉, 비상관 부질의는 임의의 로우가 주질의에 의해 검사되기 전에 논리적으로 실행될 수 있다. 즉, 부질의가 주질의에 독립적이고 그 우측에 질의로서 존재할 수 있다. 한편, 상관된 부질의는 주질의에 의해 검사되는 로우에 의존한다.
1. 이하 SQL 문장은 상관 및 비상관된 부질의의 혼합이다. 이하 SQL 문장에서, 최종 부질의는 스칼라(scala) 부질의이고, 주위 부질의가 PROJ_SEQ 및 RPT_DATA에 상등 기준을 갖고 EMP_SEQ 컬럼이 SELECT 목록에 있으므로, SAL_HISTORY의 부질의가 할 수 없을지라도 이 부질의는 머지될 수 있다. 이는 FROM 절의 네스티드 질의가 스칼라로서 올바로 식별되었는지의 좋은 시험이다.
SELECT * FROM employees
WHERE emp_seq IN
(SELECT emp_seq FROM time_sheets t
WHERE proj_seq =
(SELECT proj_seq FROM projects
WHERE name = 'EXPLAIN SQL: DEVELOPMENT,)
AND rpt_date =
(SELECT MAX(effective_date) FROM sal_history s
WHERE s.emp_seq = t.emp_seq))
SELECT e.* FROM employees e, time_sheets t, projects p,
(SELECT emp_seq, MAX(effective_date) col1 FROM
sal_history s
GROUP BY emp_seq) x
WHEREe.emp_seq = t.emp_seq
AND t.proj_seq = p.proj_seq
AND p.name = 'EXPLAIN SQL: DEVELOPMENT'
AND t.emp_seq = x.emp_seq
AND t.rpt_date = x.col1
으로 변환되어야 한다.
2. 이하 예는 비상관적이고 직전의 예와 약간 다르다. 기본 차이는 SAL_HISTORY의 부질의이다. 이 경우 부질의는 다중 로우를 잠재적으로 리턴하기 위해 초기에 판정된다. 이는 실행 기간 에러가 원래 질의에서 가능할 수 있다는 것을 의미한다. 이는 부질의를 머지 또는 이동하지 못하게 한다. 즉, SAL_HISTORY의 부질의는 그대로 있어야 한다. 그러나, RPT_DATE의 기준이 상등 연산자를 가지므로, 부질의를 TIME_SHEETS와 머지하는 것은 여전히 발생할 수 있고 이는 잠재적으로 여전히 동일한 실행기간 에러에 직면할 것이다. 즉, 스칼라 세트를 생성하는 것을 보장할 수 없으므로 SAL_HISTORY의 부질의는 이동되지 않을 것이다. 그러나, 이 경우 이를 수행하고 이는 "rpt_date=____"에 대한 단일 상수값을 야기할 것이다. 본 발명은 상수와 등가인 것으로 부질의를 인식하여, 주위 질의가 그 주위 질의와 머지될 수 있게 하고 네스티드 선택을 함께 운반할 것이다.
예를 들면, 이하 SQL 문장
SELECT * FROM employees
WHERE emp_seq IN
(SELECT emp_seq FROM time_sheets t
WHERE proj_seq =
(SELECT proj_seq FROM projects
WHERE name = 'EXPLAIN SQL: DEVELOPMENT')
AND rpt_date =
(SELECT effective_date FROM sal_history s
WHERE sal > 100)
SELECT e.* FROM employees e, time_sheets t, projects p
WHERE e.emp_seq = t.emp_seq
AND t.proj_seq = p.proj_seq
AND p.name = 'EXPLAIN SQL: DEVELOPMENT'
AND t.rpt_date =
(SELECT effective_date FROM sal_history s
WHERE sal > 100)
으로 변환되어야 한다.
3. 이하 예는 상관적이고 ALL 연산자로 처리한다. 부질의가 로우를 리턴하지 않으면, 기준은 참으로 판정할 수 있다. 이는 부질의가 이동만 되어야 하고, 아웃터 조인 구문만이 초기 상관 기준에 이용되는 아웃터 조인으로서 수행되어야 한다는 것을 의미한다. 비교되는 원래 컬럼은 조인 일치가 없어야 한다. 추가된최종 기준은 아웃터 조인이 일어난 후 평가된다.
예를 들면, 이하 SQL 문장
SELECT emp_seq, birthdate FROM employees e
WHERE birthdate < ALL
(SELECT birthdate FROM dependents d
WHERE e.emp_seq = d.emp_seq)
SELECT e.emp_seq, e.birthdate FROM employees e,
(SELECT d.emp_seq, MIN(birthdate) col1, 1 col2 FROM
dependents d
GROUP BY emp_seq) x
WHERE e.emp_seq = x.emp_seq(+)
AND (e.birthdate < x.col1 OR x.col2 IS NULL)
으로 변환될 수 있다.
본 시스템은 그로 인해 파싱 에러를 생성될 수 있으므로 임의의 새로운 아웃터 조인된 기준이 임의의 것에 OR되는지를 판정하기 위해서 점검해야 한다. 데이터베이스가 변환이 수행되어야 할지를 알아보기 위해 중간 해를 파싱하게 하는 것이 바람직할 수 있다. 수행되어야 하지 않는다면, 부질의에 아무 것도 수행되어서는 안 된다.
4. 이하 질의는 비상관적이고, GROUP BY 구문을 갖는 부질의로 처리된다.부질의가 GROUP BY 절을 갖더라도, SELECT 목록은 GROUP BY 목록의 열 각각을 포함하지 않는다. 이는 DISTINCT 키워드가 부질의 SELECT 목록에 추가되지 않는다면 복사에 대한 잠재성이 있음을 의미한다.
예를 들면, 이하 SQL 문장
SELECT * FROM employees
WHERE emp_seq IN
(SELECT emp_seq FROM assignments
GROUP BY emp_seq, proj_seq)
SELECT e.* FROM employees e,
(SELECT DISTINCT a.emp_seq FROM assignments a
GROUP BY a.emp_seq, a.proj_seq) x
WHERE e.emp_seq = x.emp_seq
으로 변환될 수 있다.
5. SQL 문장은 애그리게이트만을 포함하지만 GROUP BY절은 포함하지 않을 수 있다. 그러므로, DISTINCT 키워드를 요구하지 않는다. 이 예는 비상관적이다.
이하 SQL 문장
SELECT * FROM employees
WHERE hiredate =
(SELECT MIN(effective_date) FROM sal_history)
SELECT e.* FROM employees e,
(SELECT MIN(s.effective_date) col1 FROM sal_history s) x
WHERE e.hiredate = x.coll
으로 변환될 수 있다.
6. 이하 예는 비상관적이고, 주위 질의로 이동할 때 NOT IN 연산자를 처리하는 것을 설명한다. 기본 요점은 본 시스템이 아웃터 조인으로 변환하여야 하고 "아웃터 조인된 로우"인 로우[예를 들면, 부질의(이하 "x.coll IS NULL" 기준 참고)의 SELECT 목록의 널가능하지 않은 컬럼이 IS NULL인]를 탐색하여야 한다는 점이다. 부질의가 GROUP BY 구문을 갖거나 갖지 않거나 작용할 것이므로, 해는 1과 같은 상수를 SELECT 목록에 추가하는 것이다.
예를 들면, 이하 SQL 문장
SELECT emp_seq FROM employees
WHERE hiredate NOT IN
(SELECT effective_date FROM sal_history)
SELECT e.emp_seq FROM employees e,
(SELECT DISTINCT effective_date, 1 col1 FROM sal_history) x
WHERE e.hiredate = x.effective_date(+)
AND x.col1 IS NULL
으로 변환될 수 있다.
7. 이하 예는 상술한 예 6과 유사하고 비상관적이다. 그러나, 이 예에서 다중 컬럼이 부질의와 인터페이스한다. 또한, 컬럼은 주위 질의의 다중 테이블을 나타낸다. 이 예에서, 변환이 파싱하지 않으므로 문제가 야기될 수 있다. 에러 메시지는 "ORA-01417: 테이블이 최대 하나의 다른 테이블에 아웃터 조인될 수 있다" 가 생성될 수 있다. 그 이유는 X가 EMPLOYEES 및 DEPENDENTS에 아웃터 조인되기 때문이다. 따라서, 이 변환은 관계형 연산자가 아웃터 조인을 요구하고 부질의를 인터페이스하는 컬럼이 다중 테이블로부터의 것일 때 생성되지 않아야 한다.
예를 들면, 이하 SQL 문장
SELECT e.emp_seq FROM employees e, dependents d
WHERE (e.hiredate, d.birthdate) NOT IN
(SELECT hiredate, d1.birthdate FROM employees e1, dependents d1
WHERE e1.emp_seq = 1001
AND e1.emp_seq = dl.emp_seq
AND relation = 'SPOUSE')
AND e.emp_seq = d.emp_seq
AND d.relation = 'SPOUSE'
SELECT e.emp_seq FROM employees e, dependents d,
(SELECT DISTINCT e1.hiredate, d1 .birthdate, 1 col1 FROM
employees el, dependents d1
WHERE e1.emp_seq = 1001
AND e1.emp_seq = d1.emp_seq
AND d1.relation = 'SPOUSE') x
WHERE e.emp_seq = d.emp_seq
AND d.relation = 'SPOUSE'
AND e.hiredate = x.hiredate(+)
AND d.birthdate = x.birthdate(+)
AND x.col1 IS NULL
으로 올바르지 않게 변환될 것이다.
8. 이하 비상관 예는 흥미롭지만 이상한 상황을 제공한다. 이 상황은 이론적으로는 일어날 수 있지만 드물게 볼 수 있다. 그 이유는 이하의 부질의가 비상관적이지만 EXISTS 연산자로써 주위 질의에 인터페이스되기 때문이다. EXISTS 연산자는 일반적으로 상관된 부질의와만 사용된다. 모든 경우에, 변환은 간단하고, 넌조인 절이 있는 주위 질의로 이를 이동시키고 이하 도시된 "ROW NUM =1" 기준을 부질의에 추가하기만 한다.
예를 들면, 이하 SQL 문장
SELECT * FROM employees
WHERE EXISTS
(SELECT * FROM sal_history
WHERE sal < 0)
SELECT e.* FROM employees e,
(SELECT * FROM sal_history
WHERE sal < 0
AND ROWNUM = 1)
으로 변환될 수 있다.
부질의가 원래 SQL 문장에서 수행된 것처럼 로우마다 한번씩 수행되는 대신에 이제 단지 한번만 실행되므로, 성능은 원래 SQL 문장에서보다 변환된 SQL 문장에서 상당히 좋아질 것이다.
9. 이하 예는 비상관적이고 부질의가 동일한 명칭을 갖는 하나 이상의 컬럼 명칭을 포함하기 때문에 나열된다. 컬럼 명칭이 테이블 애일리어스를 뒤따른다 해도, 컬럼 명칭은 애일리어스가 주어져야 한다. 또한, 주위 질의의 SELECT 목록의 아스타리스크는 주위 질의의 각 테이블에 대해 복사되어야 한다. 이하 도시된 변환에서 밑줄 그어진 항목을 주목하자.
SQL 문장
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq
AND (e.birthdate, d.birthdate) IN
(SELECT el.birthdate, dl.birthdate FROM employees e1,
dependents dl
WHERE el.emp_seq = dl .emp_seq
AND e1.hiredate = SYSDATE - 100)
SELECTe.*, d.*FROM employees e, dependents d,
(SELECT DISTINCT el.birthdatecol1, d1.birthdatecol2
FROM employees el, dependents dl
WHERE el.emp_seq = dl.emp_seq
AND el.hiredate = SYSDATE - 100)x
WHERE e.emp_seq = d.emp_seq
AND e.birthdate =x.col1
AND d.birthdate =x.col2
으로 변환될 수 있다.
10. 이하 예는 비상관적이고 스칼라 부질의 및 NOT IN 연산자를 설명한다. 부질의가 스칼라이므로, 이는 아웃터 조인으로서 주위와 합치될 수 있다. 중요한 것은 "아웃터 조인" 로우만을 유지하는 것이다. 이는 기준을 부질의의 테이블의 널이 아닌 컬럼이 있는 기준과 IS NULL 연산자를 AND하여 달성될 수 있다. 보다 좋은 해는 ROWID를 사용하는 것일 수 있다 (이하 제2 변환을 참조).
예를 들면,
SELECT emp_seq FROM employees
WHERE hiredate NOT IN
(SELECT hiredate FROM employees
WHERE emp_seq = 999)
SELECT e.emp_seq FROM employees e, employees e1
WHERE e.hiredate = e1.hiredate(+)
AND el.emp_seq(+) = 999
AND el.emp_seq IS NULL
으로 변환되거나
SELECT e.emp_seq FROM employees e, employees e1
WHERE e.hiredate = e1.hiredate(+)
AND e1.emp_seq(+) = 999
AND e1.rowid IS NULL
으로 변환될 수 있다.
11. 이하 상관된 예는 상관 기준 및 넌조인 기준 모두를 포함한다. 부질의가 고유성을 보장하므로 부질의는 합치될 수 있다.
예를 들면, SQL 문장:
SELECT * FROM employees e
WHERE EXISTS
(SELECT * FROM projects p, assignments a
WHERE p.proj_seq = a.proj_seq
AND e.emp_seq = a.emp_seq
AND p.name = 'EXPLAIN SQL: DEVELOPMENT')
SELECT e.* FROM employees e, projects p, assignments a
WHERE p.proj_seq = a.proj_seq
AND e.emp_seq = a.emp_seq
AND p.name = 'EXPLAIN SQL: DEVELOPMENT'
으로 변환될 수 있다.
12. 이하 상관된 예는 SELECT 목록이 주위 질의로 리턴되지 않는 컬럼을 포함하기 때문에 다르다. (사실상, 직전의 예 11에서 부질의가 SELECT 목록의 항목을 갖는다면, 변환은 여전히 동일할 것이다. 직전의 예 11에서 부질의 SELECT 목록 상의 아스타리스크(asterisk)는 문제되지 않는다.)
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT relation FROM dependents d
WHERE e.emp_seq = d.emp_seq)
SELECT e.* FROM employees e,
(SELECT DISTINCT emp_seq FROM dependents d) x
WHERE e.emp_seq = x.emp_seq
으로 변환될 수 있다.
13. 이 상관된 예는 SELECT 목록 컬럼이 주위 질의에서 해당 컬럼을 갖기 때문에 직전의 예와 다르다.
예를 들면,
SELECT * FROM sal_history sl
WHERE effective_date >
(SELECT MAX(effective_date) FROM sal_history s2
WHERE sl.emp_seq = s2.emp_seq)
SELECT sl.* FROM sal_history sl,
(SELECT emp_seq, MAX(effective_date) col1 FROM
sal_history s2
GROW BY emp_seq) x
WHERE sl.emp_seq = x.emp_seq
AND sl.effective_date > x.col1
으로 변환될 수 있다.
14. 이하의 비상관 예는 NOT EXISTS 연산자를 통해 인터페이스된 비상관된 부질의를 설명한다.
예를 들면,
SELECT * FROM employees
WHERE NOT EXISTS (SELECT * FROM dependents)
SELECT e.* FROM employees e,
(SELECT count(*)col1 FROM dependents WHERE R0WNUM = 1) x
WHERE x.col1 = 0
으로 변환될 수 있다.
원래 부질의의 SELECT 목록이 "COUNT(*)"로 변경되고 "ROWNUM=1" 기준이 부질의에 추가되었음을 주의하자.
15. 이하의 비상관 예는 부질의가 GROUP BY를 포함하는 것을 제외하면 직전의 예 14와 유사하다. 변환은 직전의 예 14와 유사하다.
예를 들면,
SELECT * FROM employees
WHERE NOT EXISTS
(SELECT nu11 FROM sal_history
GROUP BY emp_seq)
SELECT e.* FROM employees e,
(SELECT count(*)col1 FROM sal_history
WHERE ROWNUM = 1
GROUP BY emp_seq) x
WHERE x.col1 = 0
으로 변환될 수 있다.
부질의의 SELECT 목록이 무엇이었든지 간에 "COUNT(*)"로 스왑(swap)된다.
16. 이하는 NOT EXISTS 연산자를 사용하는 상관된 예이다.
예를 들면,
SELECT emp_seq FROM employees e
WHERE NOT EXISTS
(SELECT * FROM sal_history s
WHERE e.emp_seq = s.emp_seq
AND effective_date = SYSDATE)
SELECT e.emp_seq FROM employees e, sal_history s
WHERE e.emp_seq = s.emp_seq(+)
AND effective_date(+) = SYSDATE
AND s.emp_seq IS NULL
으로 변환될 수 있다.
17. 이하의 상관 예는 IN 연산자와 인터페이스하는 세트 부질의를 설명한다.
예를 들면,
SELECT * FROM sal_history sl
WHERE effective_date IN
(SELECT effective_date FROM sal_history s2
WHERE sl.emp_seq = s2.emp_seq
AND sal > 100)
SELECT sl.* FROM sal_history sl, sal_history s2
WHERE sl.effective_date = s2.effective_date
AND sl.emp_seq = s2.emp_seq
AND s2.sal> 100
으로 변환될 수 있다.
18. 이하의 비상관 예는 < ALL 연산자를 설명한다.
예를 들면
SELECT * FROM employees
WHERE hiredate < ALL
(SELECT hiredate FROM employees
WHERE birthdate > '01-JAN-87')
SELECT e.* FROM employees e,
(SELECT MIN(hiredate) col1 FROM employees
WHERE birthdate > '01-JAN-87') x
WHERE (hiredate < x.col1 OR x.col1 IS NULL)
으로 변환될 수 있다.
변환에서 "x.coll IS NULL"의 사용을 주의하자. 주의점은 애그리게이트 함수는 로우가 기준을 만족시키지 못하여도 항상 값을 리턴할 것이라는 점이다. ALL 연산자는 부질의가 공집합을 내놓을 때 참으로 판정하므로, 본 시스템은 주위 질의의 로우를 여전히 리턴해야 한다.
19. 이하의 비상관 예는 직전의 예 18과 유사한다. 그러나, 이 예에서 > ALL 연산자는 < ALL 대신 사용된다.
예를 들면,
SELECT * FROM employees
WHERE hiredate > ALL
(SELECT hiredate FROM employees
WHERE birthdate > '01-JAN-77')
SELECT e.* FROM employees e,
(SELECT MAX(hiredate) col1 FROM employees
WHERE birthdate > 'Ol-JAN-77') x
WHERE (hiredate > x.col1 OR x.col1 IS NULL)
으로 변환될 수 있다.
20. 이하의 비상관 예는 머지 가능한 세트 부질의를 포함한다.
예를 들면,
SELECT * FROM employees
WHERE emp_seq NOT IN
(SELECT emp_seq FROM sal_history
WHERE effective_date = '5-JUL-98')
SELECT e.* FROM employees e, sal_history s
WHERE e.emp_seq = s.emp_seq (+)
AND effective_date(+) = '5-JUL-98'
AND s.emp_seq IS NULL
으로 변환될 수 있다.
21. 이하의 상관된 예는 상관된 것을 제외하고는 직전의 예 20과 유사하다. 이 예는 상관 기준에 아웃터 조인 구문을 추가하는 방법을 설명한다.
예를 들면,
SELECT * FROM assignments a
WHERE start_date NOT IN
(SELECT effective_date FROM sal_history s
WHERE a.emp_seq = s.emp_seq)
SELECT a.* FROM assignments a, sal_liistory s
WHERE astart_date = s.effective_date(+)
AND a.emp_seq = s.emp_seq(+)
AND s.emp_seq IS NULL
으로 변환될 수 있다.
22. 이하의 비상관 예는 직전의 예 21과 유사하다. 그러나, 이 예에서, 부질의는 다중 테이블을 구비한다. 이 예는 주위 질의에 합치될 때 부질의 내의 조인 기준에 아웃터 조인 구문을 놓는 방법을 이하 설명한다.
예를 들면,
SELECT * FROM status_list
WHERE status s NOT IN (SELECT p.status
FROM projects p, assignments a
WHERE a.proj_seq = p.proj_seq
AND p.name = 'EXPLAIN SQL: DEVELOPMENT')
SELECT s.* FROM status_list s, projects p, assignments a
WHERE s.status = p.status(+)
AND p.name(+) = 'EXPLAIN SQL: DEVELOPMENT,
AND a.proj_seq(+) = p.proj_seq
AND a.ROWID IS NULL
으로 변환될 수 있다.
이 부질의에서, 고유성이 중간 조인된 테이블에서 보장된다(이 경우 p.name이 고유(unique)하므로 "p"로 칭함). 최대 하나의 최저 레벨의 자식(child)이 이 경우 비고유(non-unique) 애일리어스 "a"일 수 있다. 조인 순서는 애일리어스 "s", "p", "a"의 순서이다.
23. 이하의 상관된 예는 보다 복잡할 수 있다. NOT IN 연산 때문에 아웃터 조인이어야 한다. 그러나, 애일리어스 "e" 및 "a" 모두가 부질의와 상관된다는 것이 문제이다. 부질의는 부질의가 단지 하나의 테이블만을 포함하기 때문에 머지될 수 있어야 하고, 그러므로 고유성을 보장할 필요가 없다.
예를 들면,
SELECT * FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND e.emp_seq NOT IN
(SELECT t.emp_seq FROM time_sheets t
WHERE a.proj_seq = t.proj_seq
AND t.rpt_date = '20-FEB-94')
이다.
부질의는 상관 기준 때문에 머지되거나 이동될 수 없다. 부질의의 상관 기준 및 인터페이스 컬럼이 주위 질의의 하나 이상의 테이블을 참조한다면, 부질의는 건너 뛸 수 있다. 이 경우 하나의 상관 기준은 애일리어스 "a"를 참조하고 주위질의의 인터페이스는 "e.emp_seq"를 참조한다. 본 시스템이 부질의를 변환한다면, 변환은 유효하지 않은 하나 이상의 테이블로 아웃터 조인된 TIEM_SHEETS으로 종료될 것이다.
상술한 SQL 문장은
SELECT * FROM employees e, assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND e.emp_seq = t.emp_seq(+)
AND a.proj_seq = t.proj_seq(+)
AND t.rpt_date(+) = '20-FEB-94'
AND t.emp_seq IS NULL
으로 올바르지 않게 머지되고
SELECT * FROM employees e, assignments a,
(SELECT t.emp_seq, t.proj_seq, 1 col1 FROM time_sheets t
WHERE t.rpt_date = '20-FEB-94') x
WHERE e.emp_seq = a.emp_seq
AND e.emp_seq = x.emp_seq(+)
AND a.proj_seq = x.proj_seq(+)
AND x.col1 IS NULL
으로 올바르지 않게 이동된다.
이 경우 모두는 위반(illegal) 아웃터 조인을 야기하고, 방지되어야 한다.
24. 이하의 상관예는 상기 예 23과 유사하다. 이행성을 통하여 시스템은 예 23에 나타낸 바와 같이 원문을 다음과 같은 원문으로 변환한 후에 변환을 행함으로써, 예 23에서 있었던 제한을 제거할 수 있다.
예를 들면, 예 23의 원문은,
SELECT * FROM employees e, assignments a
WHERE e.emp_seq = a.emp seq
AND a.emp_seq NOT IN
(SELECT t.emp_seq FROM time_sheets t
WHERE a.proj_seq = t.proj_seq
AND t.rpt_date = `20-FEB-94')
로 변환될 수 있고,
SELECT * FROM employees e, assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq(+)
AND a.proj_seq = t.proj_seq(+)
AND t.rpt_date(+) = `20-FEB-94'
AND t.emp_seq IS NULL
로 차례로 변환될 수 있다.
25. 다음의 상관예는 스칼라 연산자 "="를 취급한다. 이 예는 부질의가 스칼라인지를 판단하기 위해서 부질의에서의 이행성이 어떻게 사용될 수 있는지, 예를 들면 "e.emp_seq=t.emp_seq=a.emp_seq"를 나타낸다.
예를 들면,
SELECT * FROM time sheets t, projects p
WHERE t.proj_seq = p.proj_seq
AND t.rpt_date =
(SELECT hiredate FROM employees e, assignments a
WHERE a.proj_seq = p.proj_seq
AND e.emp_seq = a.emp_seq
AND e.emp_seq = t.emp_seq)
는,
SELECT * FROM time_sheets t, proj ects p, employees e, assignments a
WHERE t.proj_seq = p.proj_seq
AND t.rpt_date = e.hiredate
AND a.proj_seq = p.proj_seq
AND e.emp_seq = t.emp_seq
AND e.emp seq = a.emp_seq
로 변환될 수 있다.
26. 다음의 상관예는 집합 연산자 "IN"를 취급한다.
예를 들면,
SELECT * FROM employees e
WHERE emp_seq IN
(SELECT a.emp_seq FROM assignments a, time_sheets t
WHERE a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND a.proj_seq = 1
AND t.rpt_date = `20-FEB-94')
는,
SELECT * FROM employees e, assignments a time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND a.proj_seq = 1
AND t.rpt_date = `20-FEB-94'
로 변환될 수 있다.
27. 다음의 상관예는 상관 기준이 부질의 내의 테이블 중의 하나 이상을 포함하지만 머지가 가능한 것을 나타낸다. 이 경우, "t."는 인터페이스를 통하여 "e."를 부질의에 인터페이스하고; 그 후 "t."가 PROJ_SEQ 컬럼을 통하여 "a"와 상관된다. 이행성은 "t"가 PROJ_SEQ와 EMP_SEQ 컬럼 양쪽을 통하여 "a"와 상관되도록 적용될 수 있다. 또한, 조인 시 "e" 및 "a"에 대하여 유일성이 보증된다.
예를 들면,
SELECT * FROM time_sheets t
WHERE t.rpt_date NOT IN
(SELECT hiredate FROM employees e, assignments a
WHERE a.proj_seq = t.proj_seq
AND e.emp_seq = a.emp_seq
AND e.emp_seq = t.emp_seq)
는,
SELECT t.* FROM time_sheets t, employees e, assignments a
WHERE t.rpt_date = e.hiredate(+)
AND t.emp_seq = e.emp_seq(+)
AND t.proj_seq = a.proj_seq(+)
AND t.emp_seq = a.emp_seq(+)
AND (a.emp_seq IS NULL OR e.emp_seq IS NULL)
로 변환될 수 있다.
"a" 및 "e"는 별개로 "t"에 결합되므로, 시스템은 각 테이블의 공백이 없는 컬럼과 이들과 함께 OR에 IS NULL을 가산할 필요가 있다.
28. 다음의 상관예는 GROUP BY 절을 갖는 부질의의 SELECT 리스트 상의 애그리게이트를 나타낸다.
예를 들면,
SELECT * FROM sal_history s
WHERE effective_date IN
(SELECT MAX(start_date) FROM assignments a
WHERE s.emp_seq = a.emp_seq
GROUP BY proj_seq)
는,
SELECT * FROM sal_history s
(SELECT DISTINCT emp_seq, MAX(start_date) coll FROM assignments a
GROUP BY proj_seq, emp seq) x
WHERE s.emp_seq = x.emp_seq
AND effective_date = x.coll
로 변환될 수 있다.
29. 다음의 비상관예는 부질의가 이동된 때에 애그리게이트를 애그리게이트의 애그리게이트로 변환하는 것을 나타낸다.
예를 들면,
SELECT * FROM assigrnnents a
WHERE start_date < ANY
(SELECT MIN(rpt_date) FROM time_sheets
GROUP BY proj_seq)
는,
SELECT * FROM assignments a,
(SELECT MAX(MIN(rpt_date)) coll FROM time_sheets
GROUP BY proj_seq) x
WHERE a.start_date < x.coll
로 변환될 수 있다.
30. 다음의 상관예는 "<ANY"와 같은 연산자를 통하여 인터페이스된 부질의가 변환될 수 없을 때를 나타낸다.
예를 들면,
SELECT * FROM assignments a
WHERE start_date < ANY
(SELECT MIN(rpt_date) FROM time_sheets t
WHERE a.emp_seq = t.emp_seq
GROUP BY proj_seq)
는,
SELECT * FROM assignments a,
(SELECT emp_seq, MIN(rpt_date) coll FROM time_sheets t
GROUP BY proj_seq, emp_seq) x
WHERE a.start_date < x.coll
AND a.emp_seq = x.emp_seq
로 INCORRECTLY 변환된다.
이 변환은 부질의가 아직 세트이고 필요에 따라 스칼라가 아니기 때문에 부정확하다. 예를 들면, EMP_SEQ에 대하여, PROJ_SEQ에 의한 GROUP화로 인해 많은 MIN(rpt_date)가 아직 잠재적으로 있다. 부질의가 GROUP BY 절을 갖지 않은 경우에도, SELECT 리스트 상의 상관 컬럼을 놓고 애그리게이트, 애그리게이트의 애그리게이트를 이루는 변환이 요구되므로, 아직 변환을 쉽게 할 수 없다. 이는, 스칼라 및 애그리게이트의 애그리게이트의 구문 위반으로 된다.
원래의 GROUP BY 컬럼이 상관되지도 않고 HAVING 절 부분도 아니더라도, 시스템은 이것을 면할 수 없다.
예를 들면, 질의가,
SELECT e.* FROM employees e,
(SELECT emp_seq, MAX(rpt_date) coll FROM time_sheets t
GROUP BY t.emp_seq) x
WHERE e.emp_seq = x.emp_seq
AND e.hiredate < x.coll
로 부적확하게 변환될 수 있다.
상기 변환은, 동일한 PROJ_SEQ에 대하여 rpt_date가 e.hiredate보다 적지만 다른 rpt_date는 e.hiredate보다 크게 될 수 있으므로 부정확한다. 원래의 질의에서, MIN(rpt_date)를 갖는 부질의는 로우들의 하나로서 제1 데이터로 복귀할 것이다. 그러나, 상기 질의에서, 부질의는 최대값으로 복귀할 것이다.
31. 다음의 상관예는 "=" 연산자 대신에 "<" 연산자를 사용하는 상관 기준 때문에 부질의가 이동될 수 없는 우수한 예이다.
예를 들면,
SELECT * FROM sal_history s1, employees e
WHERE e.emp_seq = sl.emp_seq
AND s1.effective_date =
(SELECT MIN(s2.effective_date)
FROM sal_history s2
WHERE e.emp_seq = s2.emp seq
AND e.hiredate < s2.effective_date)
는,
SELECT * FROM sal_history s1, employees e,
(SELECT s2.emp_seq, s2.effective_date, MIN(s2.effective_date) coil
FROM sal_history s2
GROUP BY s2.emp_seq, s2.effective_date) x
WHERE e.emp_seq = x.emp_seq
AND sl.effective_date = x.coll
AND e.hiredate < x.effective_date
로 INCORRECTLY 변환된다.
정확한 변환을 행하는 하나의 방법은 부등식 상관에 포함되는 테이블을 다음과 같이 부질의로 이동하도록 하는 것이다 :
SELECT * FROM sal_history s1,
(SELECT e.emp_seq, MIN(s2.effective_date) coll
FROM sal_history s2, employees e
WHERE e.emp_seq = s2.emp_seq
AND e.hiredate <s2.effective_date
GROUP BY e.emp_seq) x
WHERE sl.emp_seq = x.emp_seq
AND sl.effective_date = x.coll
이 해법은 EMPLOYEES 테이블을 부질의로 이동시킨 후에, 부질의를 이동시키는 것이다.
32. 다음의 상관예는 애그리게이트가 없는 스칼라 부질의다.
예를 들면,
SELECT * FROM sal_history s
WHERE effective_date =
(SELECT hiredate FROM employees e
WHERE s.emp_seq = e.emp_seq)
는,
SELECT s.* FROM sal history s, employees e
WHERE s.effective_date = e.hiredate
AND s.emp_seq = e.emp_seq
로 변환될 수 있다.
33. 다음의 상관예는 직전의 예 32와 유사하다. 그러나, 이 예에서는 고유 키 부분이 아닌 컬럼 상에 추가적인 상관 기준이 있다. 이는 상관 부질의들을 취급할 때에 중요할 수 있고, 부질의의 PK 또는 UNQ 키 상의 상관 기준은 "=" 연산자를 사용해야 하고, 추가적인 상관 기준에서 사용된 연산자는 상관없다. 이 경우 상관 기준 "t.rpt_date>=a.start_date"는 고유 키 부분이 아니다.
예를 들면,
SELECT * FROM time_sheets t
WHERE rpt_date <
(SELECT stop_date FROM assignments a
WHERE a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date >= a.start_date)
는,
SELECT t.* FROM time_sheets t, assignments a
WHERE t.rpt_date < a.stop_date
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date >= a.start_date
로 변환될 수 있다.
34. 다음의 상관예는 스칼라 연산자를 사용하여 스칼라 부질의를 인터페이스하고, 여기서 부질의는 애그리게이트로 인해 스칼라이고 GROUP BY 절은 아니다.
예를 들면,
SELECT * FROM employees e
WHERE hiredate>
(SELECT MIN(effective_date) FROM sal_history s
WHERE e.emp_seq = s.emp_seq)
는,
SELECT e.* FROM employees e,
(SELECT emp_seq, MIN(effective_date) coll FROM sal_history s
GROUP BY emp_seq) x
WHERE e.emp_seq = x.emp_seq
AND e.hiredate > x.coll
로 변환될 수 있다.
35. 다음의 상관예는 HAVING 절 내의 상관을 나타낸다. 해법은 HAVING 절이 주위 질의에서의 기준으로되는 것이고, 상관 기준에 비교된 로컬 아이텀이 부질의의 SELECT 리스트 내에 나타나야만 한다. 검사할 다른 구문은 부질의가 GROUP BY를 갖지 않지만 HAVING 절을 갖는 것이다.
예를 들면,
SELECT * FROM employees e
WHERE NOT EXISTS
(SELECT a.proj_seq FROM assignments a, time_sheets t
WHERE a.proj_seq = t.proj_seq
AND a.emp_seq = t.emp_seq
AND e.emp_seq = a.emp_seq
GROUP BY a.proj_seq
HAVING MIN(t.rpt_date) < e.hiredate)
는,
SELECT * FROM employees e,
(SELECT a.proj_seq, a.emp_seq, MIN(t.rpt_date) coll, 1 col2
FROM assignments a, time_sheets t
WHERE a.proj_seq = t.proj_seq
AND a.emp_seq = t.emp_seq
GROUP BY a.proj_seq, a.emp_seq) x
WHERE e.emp_seq = x.emp_seq(+)
AND x.coll < e.hiredate(+)
AND x.col2 IS NULL
로 번역될 수 있다.
36. 다음은 연산자가 NOT IN 연산자이고 부등식 상관 임계가 있는 상관예이다. 시스템은 EMP_SEQ 컬럼의 다른 카피가 이미 존재하기 때문에 이것을 GROUP BY절로 이동시키지 않는다.
예를 들면,
SELECT * FROM sal_history s1
WHERE sl.sal NOT IN
(SELECT MIN(sal) FROM sal_history s2
WHERE s1.emp_seq != s2.emp_seq
AND s1.effective_date = s2.effective_date
GROUP BY emp_seq)
는,
SELECT sl.* FROM sal_history sl,
(SELECT emp_seq, effective_date MIN(sal) coll, 1 col2
FROM sal_history s2
GROUP BY emp_seq, effective_date) x
WHERE sl.sal = x.coll(+)
AND sl.emp_seq != x.emp_seq(+)
AND s1.effective_date = x.effective_date(+)
AND x.col2 IS NULL
order by s1.emp_seq, s1.effective_date
로 변환될 수 있다.
37. 이 상관예는 예 30에서 부질의가 애그리게이트를 갖지 않는 것을 제외하고는 상기 예 30가 유사하다. 이 질의가 실용적일 수 없지만, 이 예는 GROUP BY를 갖는 부질의가 ANY, SOME 또는 ALL 연산자 중의 어느 것에 대하여 이동되지 않아야하는 이유를 도시하기 위해서 사용된다.
예를 들면,
SELECT * FROM assignments a
WHERE start_date < ALL
(SELECT rpt_date FROM time_sheets t
WHERE a.emp_seq = t.emp seq
GROUP BY rpt_date
HAVING COUNT(*) > 1)
는,
SELECT a.* FROM assignments a,
(SELECT MIN(rpt_date) coll, emp_seq, 1 col2 FROM time_sheets t
WHERE a.emp_seq = t.emp_seq
GROUP BY rpt_date, emp_seq
HAVING COUNT(*) > 1) x
WHERE (stail_date < x.coll OR x.col2 IS NIJLL)
AND a.emp_seq = x.emp_seq(+)
로 INCORRECTLY 변환된다.
RPT_DATE에 의한 그룹화가 이미 존재하고 있어, 주위 질의에 대한 결합 기준이 없다는 문제점이 있다. 따라서, 우리는 스칼라를 필요로 할 때 EMP_SEQ 상에서 결합에 대하여 세트로 끝낸다.
38. 다음의 상관예는 ANY, SOME 또는 ALL 부질의가 부등식 상관 기준에 이동될 수 없는 경우를 나타낸다. 이동하려면, 최종 변환은 많아야 하나의 로우를 원래의 주위 질의와 비교하는 것을 보증해야만 한다. 그러나, 변환에서의 부등식 결합 기준에 따라, 복수의 로우들이 결합될 수 있다.
예를 들면,
SELECT * FROM sal_history sl
WHERE sal <ANY
(SELECT sal FROM sal_history s2
WHERE sl emp_seq != s2.emp_seq
AND s1.effective_date = s2.effective_date)
는,
SELECT sl.* FROM sal history s1,
(SELECT emp_seq, effective_date, MAX(sal) coll FROM sal_history s2) x
WHERE sl.sal < x.coll
AND sl.emp_seq != x.emp_seq
AND s1.effective_date = x.effective_date
로 INCORRECTLY 번역된다.
39. 다음은 ">ALL" 연산자를 갖는 상관예이다. 이 예는 MIN 함수 대신에 MAX 함수를 사용하는 것을 제외하고는 상기 예 3과 유사하다.
예를 들면,
SELECT emp_seq, birthdate FROM employees e
WHERE birthdate > ALL
(SELECT birthdate FROM dependents d
WHERE e.emp_seq = d.emp_seq)
는,
SELECT e.emp_seq, e.birthdate FROM employees e,
(SELECT d.emp_seq, MAX(birthdate) coll, 1 col2 FROM dependents d
GROUP BY emp_seq) x
WHERE e.emp_seq = x.emp_seq(+)
AND (e.birthdate > x.coll OR x.col2 IS NULL)
로 변환될 수 있다.
40. 다음의 상관예는 "<ANY" 연산자를 나타낸다. "<ANY"와 ">ANY" 연산자 간의 차만이 MAX가 MIN으로 되는 것이다.
예를 들면,
SELECT * FROM sal history s1
WHERE emp_seq = 1001
AND sal < ANY
(SELECT sal FROM sal_history s2
WHERE s1.emp_seq = s2.emp_seq
AND s1.effective_date = s2.effective_date)
는,
SELECT s1.* FROM sal history si,
(SELECT emp_seq, effective_date MAX(sal) coll FROM sal_histoiy s2
GROUP BY emp_seq, effective_date) x
WHERE emp_seq = 1001
AND sl.sal < x.coll
AND sl.emp_seq = x.emp_seq
AND s1.effective_date = x.effective_date
로 변환될 수 있다.
41. 다음의 상관예는 스칼라 연산자 "="를 나타낸다.
예를 들면,
SELECT * FROM employees e
WHERE hiredate =
(SELECT MIN(effective_date) FROM sal_history s
WHERE e.emp_seq = s.emp_seq)
는,
SELECT e.* FROM employees e,
(SELECT emp_seq, MIN(effective_date) coll FROM sal_histoiy s
GROUP BY emp_seq) x
WHERE hiredate = x.coll
AND e.emp_seq = x.emp seq
로 변환될 수 있다.
42. 다음의 상관예는 부질의가 HAVING 절을 포함하지만 GROUP BY 또는 애그리게이트를 포함하지 않는 EXISTS 연산자를 나타낸다. 여기서, HAVING 절 전에 GROUP BY 절을 추가하는 것이 포인트이다.
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT null FROM sal_history s
WHERE e.emp_seq = s.emp_seq
HAVING COUNT(*) > 1)
는,
SELECT e.* FROM employees e,
(SELECT emp_seq FROM sal_history s
GROUP BY emp_seq
HAVING COUNT(*) > 1) x
WHERE e.emp_seq = x.emp_seq
로 변환될 수 있다.
43. 이 상관예는 HAVING 절이 있는 직전의 예 42와 유사하다. 그러나, 이 예에서는 GROUP도 또한 존재한다.
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT null FROM sal_history s
WHERE e.emp_seq = s.emp_seq
GROUP BY effective_date
HAVING COUNT(*) > 1)
는,
SELECT e.* FROM employees e,
(SELECT DISTINCT emp_seq FROM sal_history s
GROUP BY effective_date, emp_seq
HAVING COUNT(*) > 1) x
WHERE e.emp_seq = x.emp_seq
로 변환될 수 있다.
44. 다음의 비상관예는 부질의가 EXISTS 연산자에 대하여 이동될 수 없는 경우를 나타낸다. 그 이유는 해법이 "ROWNUM=1" 기준을 부질의에 추가하는 것이기 때문이다. 그러나, HAVING 절은 검색된 로우만을 실격시킬 수 있다. 이 예에서는부질의가 빈 세트로 복귀하는 것 외에 적합한 적어도 2개의 로우가 있어야만 한다.
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT null FROM sal_history s
HAVING COUNT(*) > 1)
는,
SELECT * FROM employees e,
(SELECT null FROM sal_history s
WHERE ROWNUM = 1
HAVING COUNT(*) > 1)
로 INCORRECTLY 변환된다.
45. 다음의 상관예는 상기 복수 레벨에 상관된 부질의를 나타낸다. 이 예는, 상기 섹션에서 "제한"이 이들 종류의 상관 부질의를 변환하도록 시도해야 하는 것을 표시하기 때문에 포함된다. 이것은 비교적 복잡하기 때문에, 이하에 나타낸 바와 같이 할 수 있다.
예를 들면,
SELECT * FROM employees e
WHERE EXISTS
(SELECT null FROM assignments a
WHERE a.emp_seq = e.emp seq
AND EXISTS
(SELECT null FROM time_sheets t
WHERE t.emp_seq = e.emp_seq
AND t.proj_seq = a.projseq))
는, 우선
SELECT e.* FROM employees e
WHERE EXISTS
(SELECT null FROM assignments a,
(SELECT DISTINCT emp_seq, proj_seq FROM time_sheets t) xl
WHERE a.emp_seq = e.emp_seq
AND xl.emp_seq = e.emp_seq
AND xl.proj_seq = a.proj_seq)
로 변환될 수 있고, 다음에
SELECT e.* FROM employees e,
(SELECT DISTINCT a.emp_seq coll, xl.emp_seq col2 FROM assignments a,
(SELECT DISTINCT emp_seq, proj_seq FROM time_sheets t) xl
WHERE xl.proj_seq = a.proj_seq) x2
WHERE x2.coll = e.emp_seq
AND x2.col2 = e.emp_seq
로 변환될 수 있다.
1차 변환은 비교적 간단하다. 부질의가 머지될 수 없어, 이동되었다. 이는 선택 리스트로 이동될 상관 기준의 부분이었던 로컬 컬럼 외에, 선택 리스트에서 DISTINCT 키워드가 요구된다.
2차 변환은 현재 동일한 이름을 갖는 부질의의 상이한 로컬 테이블로부터 2개의 컬럼이 있지만 주위 질의에 상관되어 있기 때문에 보다 복잡한 비트이다. 이는 선택 리스트로 이동되었을 때에 단일의 에일리어스가 주어지는 것을 의미한다. 그 후 시스템만이 상관 기준을 주위 질의로 이동하도록 한다.
이것을 보다 최적화하기 위해서, 시스템은 이동 전에 기준의 이행성을 통지해야만 한다. 예를 들면, 우리는 "a.emp_seq = e.emp_seq"와 "x1.emp_seq = e.emp_seq"도 갖는다. 이는 "a.emp_seq = x1.emp_seq"라는 것과 등가이다. 이는 보다 유효한 부질의에서의 조인이 되는 것으로 인지하면,
SELECT e.* FROM employees e,
(SELECT DISTINCT a.emp_seq coll, xl.emp_seq col2 FROM assignments a,
(SELECT DISTINCT emp_seq, proj_seq FROM time_sheets t) xl
WHERE xl.proj_seq = a.proj_seq
AND a.emp_seq = xl.emp_seq) x2
WHERE x2.coll = e.emp_seq
AND x2.col2 = e.emp_seq
로 된다.
46. OR 연산자는 부질의의 부모로 간주된다. 다음의 예는 조인으로의 변환이 오답을 생성하는 경우를 나타낸다.
예를 들면,
SELECT count(*) FROM employees
WHERE hiredate > `01-jan-97'
OR emp_seq IN (SELECT emp_seq FROM sal_history
WHERE sal> 100)
OR를 무시한 경우, 변환은,
SELECT count(*)
FROM employees e, (SELECT DISTINCT emp_seq FROM sal_history WHERE sal>100) x
WHERE hiredate > `01-jan-97'
OR e.emp_seq = x.emp_seq
로 될 것이다.
문제를 알기 위한 하나의 방법은 다음과 같이 OR를 UNION ALL로 지금 변환하는 것이다:
SELECT count(*)
FROM employees e, (SELECT DISTINCT emp_seq FROM sal_history WHEREsal>100) x
WHERE hiredate > `01-jan-97'
UNION ALL
SELECT count(*)
FROM employees e, (SELECT DISTINCT emp_seq FROM sal_history WHERE sal>100) x
WHERE hiredate> `01-jan-97'
47. 다음의 예는 OR 상관 기준을 취급한다. 상관 기준이 OR이면, 아우터 조인(outer-join)으로의 변환이 불가능하고, NOT IN으로의 변환은 복잡하다.
예를 들면,
SELECT * FROM employees e
WHERE NOT EXISTS (SELECT * FROM sal_history s
WHERE s.effective_date = e.birthdate
OR s.effective_date = e.hiredate)
NOT으로의 변환이 수행되었을 경우, 시스템은 다음과 같이 해야만 한다:
SELECT * FROM employees e
WHERE birthdate NOT IN (SELECT effective_date FROM sal_history s)
OR hiredate NOT IN (SELECT effective_date FROM sal_history s)
해석 불가능한 구문을 생성하기 때문에 아우터 조인으로의 변환이 불가능하지 않은 경우:
SELECT e.* FROM employees e, (SELECT DISTINCT effective_date FROM sal_history) x
WHERE e.birthdate = x.effective_date(+)
OR e.hiredate = x.effective_date(+)
48. 다음의 예는 원래 부질의가 빈 세트를 생성할 수 있을 때 NOT EXISTS로의 NOT IN을 나타낸다. 부질의를 인위적으로 하여 증명을 위한 빈 세트를 생성했다.
예를 들면,
SELECT * FROM employees
WHERE hiredate NOT IN
(SELECT effective_date FROM sal_history
WHERE 1 = 2)
는 동일한 결과 세트가 생성되는 것을 보증하도록 다음과 같이 변환되어야 한다:
SELECT * FROM employees e
WHERE NOT EXISTS
(SELECT * FROM sal_history s
WHERE 1=2
AND e.hiredate = s.effective_date)
AND (e.hiredate IS NOT NULL
OR NOT EXISTS (SELECT * FROM sal_histoiy
WHERE 1 = 2)
그러나, 이 해법이 갖는 문제는 우리가 재차 오리지널로 복귀한다는 것이다.
49. 다음의 상관예는 주위 질의에 상관된 애그리게이트를 갖는 HAVING 절을 나타낸다.
예를 들면,
SELECT * FROM projects p
WHERE EXISTS
(SELECT null FROM time_sheets t
WHERE t.proj_seq = p.proj_seq
GROUP BY emp_seq
HAVING MIN(t.rpt_date) = p.start_date)
이 변환은 애그리게이트 및 상관 컬럼을 다음과 같이 SELECT 리스트로 이동하는 것을 요구할 수 있다:
SELECT * FROM projects p,
(SELECT proj_seq, MIN(rpt_date) coll FROM time_sheets
GROUP BY emp_seq, proj_seq) x
WHERE p.proj_seq = x.proj_seq
AND p.start_date = x.coll
50. 다음의 상관예는 NOT IN과의 머지를 증명한다. 변환에서의 추가 기준은 주위 질의에 인터페이싱되는 부질의 테이블의 ROWID를 포함한다. "t"가 조인오더에서 최하위 레벨의 자식이고, "e"가 "a"에 아우터 조인된 다음, "a"가 "t"에 아우터 조인되기 때문에 "a"보다는 에일리어스 "t"의 ROWID를 사용하는 것이 중요하다.
예를 들면,
SELECT emp_seq FROM employees e
WHERE e.hiredate NOT IN
(SELECT start_date FROM assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date = `01-jan-87'
AND a.proj_seq = 1)
는,
SELECT e.emp_seq FROM employees e, assignments a time_sheets t
WHERE e.hiredate = a.start_date(+)
AND e.emp_seq = a.emp_seq(+)
AND a.emp_seq = t.emp_seq(+)
AND a.proj_seq = t.proj_seq(+)
AND t.rpt_date(+) = `01-jan-87'
AND a.proj_seq(+) = 1
AND t.ROWID is null
로 변환될 수 있다.
51. 다음의 상관예는 부질의 인터페이스 컬럼이 부질의 내의 상관 테이블과 동일하지 않은 점을 제외하고는 직전의 예 50과 유사하다. 예를 들면, START_DATE는 ASSIGNMENTS에 속하지만 T.EMP_SEQ가 상관되어 다른 테이블에 속한다. 이행성이 사용된 경우, 우리는 T와 A의 조인 기준 때문에 T.EMP_SEQ를 A.EMP_SEQ로 스위칭할 수 있다.
예를 들면,
SELECT emp_seq FROM employees e
WHERE e.hiredate NOT IN
(SELECT start_date FROM assignments a, time_sheets t
WHERE e.emp_seq = t.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date = `01-jan-87'
AND a.proj_seq = 1)
가 우선 이행성을 추가하여,
SELECT emp_seq FROM employees e
WHERE e.hiredate NOT IN
(SELECT start_date FROM assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date = `01-jan-87'
AND a.proj_seq = 1)
를 산출하고, 그 후 우리는 동일한 변환을 생성하는 것을 의미하는 이전의 예 50과 같이 동일한 부질의를 갖는다.
52. 이 상관예는 인터페이스 컬럼에 대응하는 부질의 내의 테이블이 현재 TIME_SHEETS인 점을 제외하고는 예 50과 유사하다. EMPLOYEES가 TIME_SHEETS에 아우터 조인된 다음 TIME_SHEETS가 ASSIGNMENTS에 아우터 조인되는 것만이 다르다. 따라서, 추가 기준은 예 50에서와 같이 TIME_SHEETS 테이블보다는 ASSIGNMENTS의 ROWID를 이용한다.
예를 들면,
SELECT emp_seq FROM employees e
WHERE e.hiredate NOT IN
(SELECT rpt_date FROM assignments a, time_sheets t
WHERE e.emp_seq = t.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND t.proj_seq = 1)
는,
SELECT e.emp_seq FROM employees e, assignments a, time_sheets t
WHERE e.hiredate = t.rpt_date(+)
AND e.emp_seq = t.emp_seq(+)
AND t.emp_seq = a.emp_seq(+)
AND t.proj_seq = a.proj_seq(+)
AND t.proj_seq(+) = 1
AND a.ROWID is null
로 변환될 수 있다.
53. 다음의 상관예는 애그리게이트의 애그리게이트가 가능한 번역이 아닌 것을 나타낸다.
예를 들면,
SELECT * FROM projects p
WHERE stop_date IN
(SELECT MAX(MIN(rpt_date)) FROM time_sheets t
WHERE t.proj_seq = p.proj_seq
GROUP BY emp_seq
HAVING MIN(t.rpt_date) = p.start_date)
는,
SELECT * FROM projects p,
(SELECT proj_seq, MIN(rpt_date) coll, MAX(MIN(rpt_date)) col2 FROM time_sheets t
GROUP BY emp_seq, proj_seq) x
WHERE p.proj_seq = x.proj_seq
AND p.start_date = x.coll
AND p.stop_date = x.col2
로 INCORRECTLY 번역된다.
그러나, 이러한 SQL은 커파일링되지 않을 것이고 따라서 피해야 한다.
54. 다음의 상관예는 부등 상관 기준 및 애그리게이트가 가능한 번역이 아닌 것을 나타낸다.
예를 들면,
SELECT * FROM assignments a
WHERE a.emp_seq IN
(SELECT emp_seq FROM time_sheets t
WHERE t.proj_seq = a.proj seq
AND a.start_date > t.rpt date
GROUP BY emp_seq
HAVING MAX(rpt_date) < a.stop_date)
는,
SELECT * FROM assignments a,
(SELECT emp_seq, proj_seq, rpt_date, MAX(rpt_date) coll FROM time sheets t
WHERE t.proj_seq = a.proj seq
AND a.start_date > t.rpt_date
GROUP BY emp_seq, proj_seq, rpt_date,) x
WHERE a.emp_seq = x.emp_seq
AND a.proj_seq = x.proj seq
AND a.start_date > x.rpt_date
AND a.stop_date > x.coll
로 INCORRECTLY 변환된다.
여기서는 부등 기준 "a.start_date>t.rpt_date 때문에, T.RPT_DATE가 SELECT 리스트 뿐만 아니라 GROUP BY로 이동되는 것이 문제점이다. 그러나, 애그리게이트도 잘못된 그룹을 포함할 것이기 때문에SELECT 리스트로 이동될 수 없다. 실제로, MAX는 지금 RPT_DATE와 같을 것이다.
55. 다음의 상관예도 애그리게이트의 애그리게이트가 가능한 변환이 아닌 것을 나타낸다.
예를 들면,
SELECT * FROM assignments a
WHERE a.stop_date IN
(SELECT MAX(MIN(rpt_date)) FROM time_sheets t
WHERE t.proj_seq = a.proj_seq
GROUP BY emp_seq)
는,
SELECT * FROM assignments a,
(SELECT proj_seq, MAX(MIN(rpt_date)) coll FROM time_sheets t
GROUP BY emp_seq, proj_seq) x
WHERE a.stop_date = x.coll
AND a.proj_seq = x.proj_seq
로 INCORRECTLY 변환된다.
당신이 SELECT 리스트 상에서 스칼라 및 애그리게이트를 가질 수 없다는 것이 문제점이다.
최적화(Optimization)
다음은, 시스템 또는 유저에 의해 최적화 모드가 선택된 후, 본 시스템을 사용하여 대체 SQL 문장을 생성함으로써 SQL을 최적화하는 방법을 또한 리스팅한다. 최적화 목표용 힌드는 각 SQL 문장 변환에 포함되어야 한다. 시스템은 넌조인 기준 내의 모든 이행성을 결정하고, 모든 조인 오더를 결정하며, 각종의 모든 부질의 변환을 결정할 것이다.
넌조인 이행성(Non-Join Transitivity's)
간략하게, 다음의 질의를 찾는다.
SELECT * FROM employees e, assignments a time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND e.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = `SPOUSE')
이 예에서는, DEPENDENTS의 부질의 상의 기준이 "a.emp" 또는 "t.emp_SEQ) 뿐만 아니라 "e.emp_seq"인 오리지널에 인터페이싱될 수 있다. 다른 시스템은 이것을 인지하지 않을 것이다. "a.emp_seq"로 스위칭함으로써, 본 시스템은 데이터베이스가 ASSIGNMENTS 상의 연쇄 키 인덱스를 사용할 수 있게 한다.
대체 변환은 "e.emp_seq"를 다음과 같이 "a.emp_seq"로 변화시키도록 한다:
1.SELECT * FROM employees e, assignments a, time_sheets t
2.WHERE e.emp_seq = a.emp_seq
3.AND a.emp_seq = t.emp_seq
4.AND a.proj_seq = t.proj_seq
5.AND a.emp_seq IN (SELECT emp_seq FROM dependents
6.WHERE relation = `SPOUSE')
피연산자 "e.emp_seq"가 2개의 다른 값으로 대체될 수 있기 때문에, SQL은 3가지 방식(하나는 오리지널, 둘은 "e.emp_seq"를 대체할 수 있는 다른 값의 수)으로 기록될 수 있다.
멀티플 넌조인 이행성(Multiple Non-Join Transitivities)
다음은 시스템이 멀티플 넌조인 이행성을 다루는 방법을 설명한다. 예를 들면, SQL 문장,
1.SELECT * FROM employees e, assignments a, time_sheets t
2.WHERE e.emp_seq = a.emp_seq
3AND a.emp_seq = t.emp_seq
4.AND a.proj_seq = t.proj_seq
5.AND a.proj_seq = (SELECT proj_seq FROM projects
6.WHERE name = `EXPLAIN SQL: DEVELOPMENT')
7.AND e.emp_seq IN (SELECT emp_seq FROM dependents
8.WHERE relation = `SPOUSE')
가 주어진다.
2개의 다른 넌조인 기준 내의 2개의 피연산자 "a.proj_seq"(라인 5) 및 "e.emp_seq"(라인 7)는 등가 컬럼으로 대체될 수 있다. 다른 시스템은 이것을 인지하지 않을 것이다. 그러나, 본 시스템은, "e.emp_seq"(라인 7)를 "a.emp_seq"로 스위칭함으로써, 데이터베이스가 ASSIGNMENTS 상의 연쇄 키 인덱스를 사용할 수 있게 할 것이다. "e.emp_seq"를 갖는 기준은 이전 예와 동일하다. 본 시스템은 "a.proj_seq"(라인5)를 "t.proj_seq"로도 대체할 수 있다. 이는 사용될수 있는(여기서는 오리지널 값을 포함함) 잠재적으로 6(2 ×3)개의 다른 SQL 문장이 있는 것을 의미한다.
멀티 컬럼 피연산자(Multi-Column Operands)
멀티플 컬럼을 포함하는 피연산자가 무엇인가? 예를 들면:
1.SELECT * FROM employees e, sal_history s
2.WHERE e.emp_seq = s.emp seq
3.AND (s.emp_seq, s.effective date) IN
4.(SELECT emp_seq, max(effective_date)
5. FROM sal_history s1
6. WHERE effective_date <= SYSDATE
7. GROUP BY emp_seq)
기준 's.emp_seq, s.effective_date"(라인 3)은 이행성이 인가될 수 있는 넌조인 기준을 나타낸다. 조인 절이 "e.emp_seq"를 말하고 "s.emp_seq"이 등가이기 때문에, 넌조인 기준 피연산자에 대하여 2개의 옵션이 있다. 첫 번째는 오리지날이고 두 번째는 "s.emp_seq"를 "e.emp_seq"로 대체하는 것이다.
이것이 하여간 수행되어야 하는지의 질문이 있다. 질문의 이유는 피연산자 내의 양 컬럼이 동일한 테이블을 참조하기 때문이고, 양 컬럼 상에 연쇄 인덱스가 있다. 단일 컬럼만이 있는 경우에도 양 컬럼 상에 인덱싱한다.
응답이 걱정없으면, 피연산자에 다른 컬럼만을 추가하고, 다음과 같이 선택 리스트에 대응하는 컬럼을 추가한다:
SELECT * FROM employees e, sal_history s
WHERE e.emp_seq = s.emp_seq
AND "(e.emp_seq, s.emp_seq, s.effective_date) IN"
(SELECT "emp_seq", emp_seq, max(effective_date)
FROM sal_history s1
WHERE effective_date <= SYSDATE
GROUP BY emp_seq)
이것은 결정을 단순화하여, 사용할 데이터베이스를 결정한다.
OR 넌조인 기준(OR'ed Non-Join Criteria)
OR 기준이 질의 내에 존재하는 경우가 있는가? 넌조인 기준이 조인 기준의 어느 것에 OR된 경우, OR 조인 기준에 기인한 이행성은 사용될 수 없다. AND된 이행성만이 사용될 수 있다.
다음의 SQL은 OR를 갖는 질의를 나타내지만, 모든 조인 기준은 넌조인 기준에 AND된다.
SELECT * FROM employees e, assignments a, time sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj_seq = t.proj_seq
AND (e.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = `SPOUSE')
OR t.rpt_date = SYSDATE - 7)
다음의 SQL은 괄호를 사용하지 않고서 기준의 우선 순위를 지정한다. ANDs가 ORs 전에 수행되는 디폴트가 사용된다.
1.SELECT * FROM employees e, assignments a, time_sheets t
2.WHERE e.emp_seq = a.emp_seq
3.OR e.emp_seq IN (SELECT emp_seq FROM dependents
4.WHERE relation = `SPOUSE')
5.AND a.emp_seq = t.emp_seq
6.AND a.proj_seq = t.proj_seq
이 경우, 넌조인 기준에 AND된 조인 기준만이 라인 5 및 6에 있다. "e.emp_seq=a.emp_seq"인 이행성은 사용될 수 없다. 넌조인 기준에 AND된 조인 기준이 "e.emp_seq"를 전혀 참조하지 못하기 때문에, 이행값이 없다.
아우터 조인(Outer-Joins)
넌조인 기준이 존재하지만 질의 내에 아우터 조인이 있는 경우가 있는가? 다음의 예는,
SELECT * FROM employees e, assignments a, time_sheets t
WHERE e.emp_seq = a.emp_seq(+)
AND a.emp_seq = t.emp_seq(+)
AND a.proj_seq = t.proj_seq(+)
AND e.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = `SPOUSE')
를 나타낸다.
질문 내의 넌조인 기준이 "e.emp_seq"를 갖고, 등가 컬럼이 넌아우터 조인테이블로부터 있는 조인 기준이 없기 때문에, 이행값이 없다.
다음의 예는 이전과 약간 다르다.
SELECT * FROM employees e, assignments a, time sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq(+)
AND a.proj_seq = t.proj_seq(+)
AND e.emp_seq IN (SELECT emp_seq FROM dependents
WHERE relation = `SPOUSE')
이 예에서는, TIME_SHEETS가 아우터 조인 테이블만이다. 따라서 이 예에서는, 이행성 "e.emp_seq=a.emp_seq"가 사용될 수 있지만, "e.emp_seq"는 "t.emp_seq"와 같게 될 수 없다.
간단한 넌조인 기준의 이행성(Transitivity of Simple Non-Join Criteria)
다음의 질의는 이 개념을 설명하는 데 사용될 것이다.
1.SELECT * FROM employees e, dependents d
2.WHERE e.emp_seq = d.emp_seq
3.AND "d.emp_seq = 1001"
넌조인 기준은 "d.emp_seq=1001"(라인 3)이다. 조인 기준에 기초한 이행성 때문에, 질의는 다음과 같이 재기록될 수 있다:
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.ernp_seq
AND "e.emp_seq = 1001"
현재 EMPLOYEES 테이블 상에 넌조인 기준이 있다.
이것은 2개의 가능한 값을 갖는 이행성을 갖는 단일 컬럼 피연산자인 것으로 고려되어야 한다.
넌조인 기준의 이행성 및 네스티드 선택(Transitivity of Non-Join Criteria and Nested Selects)
이것은 매우 이로울 수 있는 단일 컬럼 이행성의 하나의 영역이다. 네스티드 선택이 GROUP BY 구문 또는 선택 리스트 내의 애그리게이트를 갖지 않고, 조인 컬럼 중의 하나를 참조하는 주질의 내에 넌조인 기준이 있는 경우, 넌조인 기준은 네스티드 선택으로 이동될 수 있다.
예를 들면, 넌조인 기준은 "e.emp_seq BETWEEN 1001 and 1010"(라인 4)이다.
1.SELECT * FROM employees e,
2.(SELECT DISTINCT emp_seq FROM dependents) x
3.WHERE e.emp_seq = x.emp_seq
4.AND "e.emp_seq BETWEEN 1001 and 1010"
조인 기준 및 이행성 때문에, 질의는 다음과 같이 재기록될 수 있다:
SELECT * FROM employees e,
(SELECT DISTINCT emp_seq FROM dependents
WHERE "emp_seq BETWEEN 1001 and 1010") x
WHERE e.emp_seq = x.emp_seq
AND e.emp_seq BETWEEN 1001 and 1010
요점은 다치(multiple values)를 취할 수 있는 단일 컬럼 피연산자인 것으로 간주되는 것이 아니라, 네스티드 선택 내의 기준을 간단히 복제하는 점이다.
드라이빙 테이블(Driving Table)
인덱싱되지 않은 넌조인 기준이 존재할 수 있다. 예를 들면, 인덱스 검색이 질의를 시작하는 방법이 없다. 인덱싱된 넌조인 기준을 갖는 질의가 존재할 수 있다. 그리고 최종적으로 넌조인 기준을 갖지 않는 질의가 존재할 수 있다. 다른 중요한 고려 사항은 조인 기준이 양측에서 인덱싱되는지의 여부이다. 이상 전부는 최적화 모드가 무엇인가에 따라서 고려되어야 한다.
이하에 참조되는 넌조인 기준은 하나의 피연산자가 부질의인 것을 포함한다.
또한 포텐셜 드라이빙 테이블은 하나 이상의 테이블을 갖는 모든 부질의 뿐만 아니라 주질의에 대하여 결정되어야 한다.
넌조인 기준이 존재하는 경우(If Non-Join Criteria Exist)
사용되는 최적화 모드에 기초하여 드라이빙 테이블을 결정한다.
FIRST ROWS
최적화 모드가 FIRST ROWS로 설정된 경우, From 절(아투어 조인 테이블이 아님) 내의 테이블/뷰 또는 네스티드 선택에 대하여, 인덱싱된 넌조인 기준 및 인덱싱되지 않은 넌조인 기준의 수를 카운트한다. 테이블이 소정의 인덱싱된 넌조인 기준을 갖는 경우, 테이블을 사용하여 질의를 드라이빙할 수 있다. 테이블이 인덱싱된 넌조인 기준을 갖지 않는 경우, 포텐셜 드라이빙 테이블이 소정의 인덱싱되지않은 넌조인 기준을 갖는 것이다.
ALL ROWS
최적화 모드가 ALL ROWS로 설정된 경우, From 절 내의 테이블/뷰 또는 네스티드 선택에 대하여, 인덱싱 여하간에 넌조인 기준의 수만을 카운트한다. 포텐셜 드라이빙 테이블은 소정의 넌조인 기준을 갖는 것이다.(카운트는 조인 오더를 결정함에 있어서 이후에 사용될 것이다.)
다음의 SQL 문자은 양쪽의 최적화 모드 변환을 나타내는 데 이용될 것이다.
SELECT * FROM employees e, dependents d, assignments a
WHERE e.emp_seq = d.emp_seq
AND e.emp_seq = a.emp_seq
AND lname like `SM%'
AND fname = `ED'
AND relation = `SPOUSE'
상기 SQL에 대하여, 최적화 모드가 FIRST ROWS인 경우, EMPLOYEES는 LNAME 상의 인덱싱된 넌조인 기준 때문에 구동 테이블일 수 있다(FNAME이 연쇄 인덱스의 부분인 사실을 잊을 수 있다). RELATION 상의 넌조인 기준은 인덱싱되지 않으므로, DEPENDENTS는 드라이빙 테이블일 수 ㅇ벗다. 또한, ASSIGNMENTS 상에도 넌조인 기준이 없다. 따라서, 포텐셜 드라이빙 테이블만이 EMPLOYEES이다.
상기 SQL에 대하여, 최적화 모드가 ALL ROWS인 경우, EMPLOYEES와 DEPENDENTS 둘다가 넌조인 기준을 갖기 때문에 드라이빙 테이블일 수 있다. 재차,ASSIGNMENTS는 소정의 넌조인 기준을 갖지 않으므로 드라이빙 테이블일 수 없다.
넌조인 기준이 없는 경우(If No Non-Join Criteria)
넌조인 기준이 전혀 없고, 참조 무결성을 통하여, 또는 유저 조인을 통하여 계급을 아는 경우(고유 인덱스를 사용하는 측이 부모측이고, 비고유 인덱스를 갖는 측이 자식측임), 드라이빙 테이블은 최상위 부모이어야 한다. 그리고, FIRST ROW와 ALL ROWS 최적화 모드 양쪽에 대해서 그래야만 한다.
예를 들어, 다음의 예에서 참조 무결성이 없다고 가정하면:
SELECT * FROM employees e, dependents d, assignments a
WHERE e.emp_seq = d.emp_seq
AND e.emp_seq = a.emp_seq
EMPLOYEES와 DEPENDENTS 간의 조인은 EMPLOYEES측의 고유 인덱스와 DEPENDENTS측의 비고유 인덱스를 이용한다. 따라서, EMPLOYEES는 부모로 간주되고, DEPENDENTS는 자식으로 간주된다. EMPLOYEES와 ASSIGNMENTS 간의 조인은 EMPLOYEES측의 고유 인덱스를 사용한다. 그러나, ASSIGNMENTS측에는 인덱스가 없다 (EMP_SEQ를 포함하는 인덱스는 있지만, 리딩 컬럼(leading column)일 뿐이다). 다음 섹션 "If Un-Indexed Join Criteria"에서 그 의의를 설명할 것이다.
그러므로, 상술된 일례의 경우에는, (다음 섹션에서는 ASSIGNMENTS가 또한 포텐셜 드라이버로 간주될 수 있다고 보일 것이지만) EMPLOYEES가 질의를 드라이빙하기 위한 후보일 수 있다.
하나 이상의 테이블이 최상위 테이블일 수 있는 질의에 대하여는 어떠한가?다음 SQL을 예시한다.
SELECT * FROM employees e, dept history dh, departments d
WHERE e.emp_seq = dh.emp_seq
AND dh.dept_seq = d.dept_seq
이 경우, EMPLOYEES와 DEPARTEMNTS는 둘 다 DEPT_HISTORY의 부모이다. 따라서, 둘 다 드라이빙 테이블로서 테스트될 수 있다.
언인덱스 조인 기준(Un-Indexed Join Criteria)
만일 테이블의 조인이 인덱스되어 있지 않다면, 그 테이블은 최적화 모드가 ALL ROWS인지의 여부에 대한 질의를 드라이빙하기 위한 후보이다. 비록 그 테이블이 넌조인 기준을 갖지 않는 반면에 다른 테이블들은 갖는다고 할지라도 그 테이블은 ALL ROWS 질의를 드라이빙할 수 있다는 점을 주목해야 한다. 만일 최적화 모드가 FIRST ROWS이면, 이와 같은 테이블은 그 테이블 상에 넌조인 기준이 아닌 한, 고려되지 않는다. 예를 들면, 인덱스된 기준을 갖는 테이블들에 우선 순위를 주는 이전의 규칙들을 사용한다. 다음의 예로 예시한다.
SELECT * FROM employees e, assignments a, projects p
WHERE a.proj_seq = p.proj_seq
AND e.emp_seq = a.emp_seq
상술된 질의 중에서 ASSIGNMENTS는 "a.proj_seq"에 대한 인덱스를 갖지 않는다. 그러므로, ASSIGNMENTS도 또한 ALL ROWS 최적화 모드에서 질의를 드라이빙하기 위한 후보이다.
아웃터 조인(Outer Joins)
테이블이 아웃터 조인된 것이면, 드라이빙 테이블로서 사용될 수 없다. 따라서, 다음 예에서 예시되는 바와 같이, DEPENDENTS에 대해 넌조인 기준이 있더라도, DEPENDENTS는 여전히 질의를 드라이빙하는 데 사용될 수 없다.
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq(+)
AND d.relation(+) = `SPOUSE'
FROM 절 네트티드 선택(FROM Clause Nested Selects)
다음의 질의는 아웃터 조인으로 인한 문제를 예시하는 것이다. 네스티드 선택은 넌조인 기준에서 부질의로서 역할하므로, 이 부질의는 언제나 드라이빙 테이블이어야 한다. 사실상, 아웃터 조인되지 않은 모든 네스티드 SELECTS는 넌조인 기준을 갖든지 갖지 않든지 간에 먼저 조인된다.
다음의 질의에서, 부질의가 먼저 조인되는 경우에 가장 바람직한 계획이 있게 되고, 그에 따라서 보다 효율적인 히스토리 레코드(historical record)를 선택하도록 드라이빙된다. 이는 이하의 순서화된 힌트(ORDERED hint) 섹션에서 보다 상세히 논의된다.
SELECT e.emp_seq, e.lname, e.fname, s.sal, d.dept_seq, j.job_seq
FROM employees e, sal_history s, job_history j, dept_history d,
(SELECT emp_seq, MAX(effective_date) coll FROM sal_history
GROUP BY emp_seq) xl,
(SELECT emp_seq. MAX(effective_date) coll FROM job_history
GROUP BY emp_seq) x2,
(SELECT emp_seq, MAX(effective_date) coll FROM dept_history
GROUP BY emp_seq) x3
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.emp_seq = xl.emp_seq
AND s.effective_date = xl.coll
AND j.emp_seq = x2.emp_seq
AND j.effective_date = x2.coll
AND d.emp_seq = x3.emp_seq
AND d.effective_date = x3.coll
뷰(Views)
이상적으로는, 시스템은 뷰를 포함하는 질의 뿐만 아니라 넌조인 기준에 대한 뷰 정의 그 자체를 검사해야 한다. 뷰 정의가 뷰를 포함하면, 뷰를 재귀적으로 체크하지 않을 수 있다. 한 레벨이면 충분하고, 종종은 그것조차 필요없을 수도 있다. 또한, 뷰는 복수의 테이블의 조인일 수 있다는 것을 명심하여야 한다.
프로세스를 간략히 하기 위해, 뷰를 포텐셜 드라이빙 테이블로서 간주한다.
조인 순서(Join Orders)
조인 순서를 결정하기 전에, 시스템은 어디에서 시작해야할지를 알 필요가 있다. 예컨대, 포텐셜 드라이빙 테이블/뷰 또는 From 절 중에서의 네스티드 선택이 된다 (상술된 드라이빙 테이블(Driving Tables)을 참조).
순서화된 힌트(ORDERED hint)는 조인 순서를 특정하는 데 사용될 수 있다.
먼저, 조인 순서를 특정할 SQL 문장에 대하여, 순서화된 힌트없이 이 문장을 테스트한다. 예컨대, 이는 (순서화된 힌트없는) 제1 치환 테스트일 수 있다. 다른 치환은 결정되었던 여러 드라이빙 테이블들에 기초하여 이루어질 수 있다. SQL 문장이 질의를 드라이빙할 수 있는 2개의 테이블을 갖는다면, 적어도 3번의 치환 즉, 원래의 것과, 다른 드라이빙 테이블들을 가지고 순서화된 힌트를 이용한 2가지가 있게 된다.
이 드라이빙 테이블들 중 하나를 고른다. FROM 절에 있는 오브제그들 간의 계층을 관찰하여, 어느 조인 루트(join route)가 "가장 양호한" 넌조인 기준을 충족시키는지를 검사한다 (FIRST ROWS는 인덱스 넌조인 기준이 존재하는 경우에는 이를 관찰하고, 그렇지 않은 경우에는 넌인덱스 넌조인 기준을 관찰하며, ALL ROWS는 인덱스 넌조인 기준이든지 아니든지 간에 가장 양호한 넌조인 기준을 관찰한다). 모든 오브젝트가 넌조인 기준과 조인된 후에는, 다른 조인들은 중요하지 않으며, 따라서 상술된 테이블들의 변수들을 생성하지 않는다.
다음의 일례들을 설명한다.
예 1
이하의 예는 ALL ROWS 최적화 모드에 관한 것이다.
SELECT e.* FROM employees e, time_sheets t, projects p,
(SELECT emp_seq, MAX(effective_date) coll
FROM sal_history s
WHERE sal > 100
GROUP BY emp_seq) x
WHERE e.emp_seq = t.emp_seq
AND t.proj_seq = p.proj_seq
AND p.name = `PAFO'
AND t.emp_seq = x.emp_seq
AND t.rpt_date = x.coll
RROJECTS에 대해서는 하나의 넌조인 기준이 있고, 네스티드 선택에 대해서도 하나의 넌조인 기준이 있다. 본 예의 계층은 도 10에 도시되어 있다.
도 10에 도시된 바와 같이, 계층은 네스티드 선택을 EMPLOYEES의 자식으로서 도시한다. 이는 SAL_HISTORY가 EMPLOYEES의 자식이라는 것을 알고 있기 때문에 본 경우에 동작하는 것이다. 점선은 관계가 이행성이라는 것을 나타내며, 이는 이하 보다 상세히 설명될 것이다.
이행성으로 인하여, PROJECTS가 드라이빙 테이블로서 선택되면, 가장 양호한 넌조인 기준의 방향에서 조인하기를 원할 수 있다. 이는 가능한 한 신속하게 네트티드 선택을 얻을 수 있기를 원하다는 것을 의미한다. 그러므로, 조인은 다음과 같이 되어야 한다 :
PROTECTS -> TIME SHEETS -> nested select -> EMPLOYEES
네스티드 선택이 드라이버로서 선택되면, 조인은 다음과 같이 되어야 한다 :
nested select -> TIME_SHEETS -> PROJECTS -> EMPLOYEES
이전의 SQL에서의 모든 넌조인 기준이 또한 인덱스되어 있음이 밝혀졌으므로, 동일한 조인 순서가 사용될 것이다.
예 2
다음 예는 FIRST ROW 또는 ALL_ROWS 최적화 모드에 관한 것이다.
SELECT * FROM employees e,
(SELECT DISTINCT emp_seq FROM dependents) x
WHERE e.emp_seq = x.emp_seq
AND e.emp_seq BETWEEN 1001 and 1010
EMPLOYEES와 네스티드 선택 간의 조인 기준은 양측에 인덱스된다. 그러나, 넌조인 기준은 네스티드 선택에서 중복되어야 하므로 (이행성에 관하여 상술된 섹션을 참조), 둘 모두의 오브젝트들은 질의를 드라이빙할 수 있다.
예 3
본 질의는 FIRST ROWS 최적화 모드에 사용되도록 의도된 것이다.
이는 표준 히스토리 데이터 질의로 사용된다. 여기서 포인트는 각 기준마다의 피연산자들 중 하나가 부질의인 넌조인 기준에 있다.
SELECT e.emp_seq, e.lname, e.fname, s.sal, d.dept_seq, j.job_seq
FROM employees e, sal_history s, job history j, dept_history d
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.effective_date =
(SELECT MAX(effective_date) FROM sal_history s1
WHERE s.emp_seq = s1.emp_seq
AND effective_date <= SYSDATE)
AND j.effective_date =
(SELECT MAX(effective_date) FROM job_history j1
WHERE j.emp_seq = j1.emp_seq
AND effective_date <= SYSDATE)
AND d.effective_date =
(SELECT MAX(effective_date) FROM dept_history d1
WHERE d.emp_seq = dl.emp_seq
AND effective_date <= SYSDATE)
본 예에 대한 계층은 도 11에 도시되어 있다. 점선은 이행성의 조인을 나타낸다. 히스토리 테이블들 각각은 인덱스 넌조인 기준을 갖기 때문에, 이 테이블들은 바로 조인될 수 있다. 그러므로, 히스토리 테이블들 중 어느 것이라도 드라이빙 테이블일 수 있다. 디폴트를 제외하고는, 각종 조인 순서는 다음과 같다 :
SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
또는
SAL_HISTORY -> JOB_HISTORY -> DEPT_HISTORY -> EMPLOYEES
또는
DEPT_HISTORY -> SAL_HISTORY -> JOB_HISTORY -> EMPLOYEES
또는
DEPT_HISTORY -> JOB_HISTORY -> DEPT_HISTORY -> EMPLOYEES
또는
JOB_HISTORY -> DEPT_HISTORY -> SAL_HISTORY -> EMPLOYEES
또는
JOB_HISTORY -> SAL_HISTORY -> DEPT_HISTORY -> EMPLOYEES
예 4
그런데, 예 3의 부질의들이 FROM 절로부터 이동된 것인가? 그렇다면, 네스티드 선택은 가능한 한 질의를 드라이빙할 수 있다. ALL ROWS 최적화 모드라고 가정한다.
SELECT e.emp_seq, e.lname, e.fname, s.sal, d.dept_seq, j.job_seq
FROM employees e, sal_history s, job_history j, dept_history d,
(SELECT emp_seq. MAX(effective_date) coll FROM sal_history
WHERE effective_date <= SYSDATE
GROUP BY emp_seq) xl,
(SELECT emp_seq, MAX(effective_date) coll FROM job_history
WHERE effective_date <= SYSDATE
GROUP BY emp_seq) x2,
(SELECT emp_seq, MAX(effective_date) coll FROM dept_history
WHERE effective_date <= SYSDATE
GROUP BY emp_seq) x3
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.emp_seq = xl.emp_seq
AND s.effective_date = xl.coll
AND j.emp_seq = x2.emp_seq
AND j.effective_date = x2.coll
AND d.emp_seq = x3.emp_seq
AND d.effective_date = x3.coll
본 예에 대한 계층은 도 12에 도시되어 있다. EMP_SEQ의 이행성으로 인해, 히스토리 테이블들 간에는 이행성의 조인 기준이 존재한다. 예를 들면, "s.emp_seq = x1.emp_seq"이고, "s.emp_seq = e.emp_sep"이고, "e.emp_seq = j.emp_seq"이고, "j.emp_seq = x2.emp_seq"이므로, "x1.emp_seq = x2.emp_seq"이다.
또한, 히스토리 테이블들에는 넌조인 기준이 없고, 단지 네스티드 선택이 있다는 것을 명심한다. 따라서, 히스토리 테이블들 중 어느 것도 질의를 드라이빙할 수 없다. 드라이빙 테이블에 관하여 상술된 어느 경우에도, FROM 절에서의 네스티드 부질의는 언제나 드라이빙될 수 있다.
이제, 우리는 보다 더 가능한 조인 순서를 갖게 되었다. 뷰를 더 용이하게 하기 위해, 네스티드 선택에 에이리어스(aliase)가 제공된다; 즉, SAL_HISTORY에 대한 네스티드 선택의 경우에는 S.N., DEPT_HISTORY 대한 네스티드 선택의 경우에는 DN 등이다. 또한, 이미 상술한 바와 같이, 시스템은 넌조인 기준을 갖지 않는 오브젝트들을 다시 정렬하는 데 대하여는 고려하지 않는다.
S.N. -> DN -> JN -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
S.N. -> JN -> DN -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
DN -> S.N. -> JN -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
DN -> JN -> S.N. -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
JN -> DN -> S.N. -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
JN -> S.N. -> DN -> SAL_HISTORY -> DEPT_HISTORY -> JOB_HISTORY -> EMPLOYEES
후자의 테이블들은 그 순서를 일정하게 하였음을 다시 한 번 명심한다. 최초의 순서가 변경될 수는 있지만, 다양한 조인 순서에 대하여 언제나 일정하게 유지된다.
테이블 결합(Clustered Tables)
테이블이 질의에 있어서 다른 테이블들 중 하나에 결합되려면, 이 테이블들은 다른 테이블들의 중간 조인 없이 함께 조인되어야 한다. 예를 들면, ASSIGNMENTS, PROJECTS, 및 TIME_SHEETS는 동일한 해쉬(hash) 결합에 있게 된다. 다음의 질의를 예시한다 :
SELECT * FROM employees e, assignments a, projects p, time_sheets t
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t.emp_seq
AND a.proj seq = p.proj_seq
AND a.proj_seq = t.proj_seq
AND t.rpt_date BETWEEN `01-JAN-97'
AND `30-JAN-97'
본 예의 계층은 도 13에 도시되어 있다. 이행성의 조인 관계는 도 13에서 점섬으로 나타나 있다. 오직 TIME_SHEETS만이 넌조인 기준을 갖는다. 따라서, TIME_SHEETS가 바로 드라이버가 된다. 그 밖에 어디서든지 넌조인 기준의 결합 및 부족(lack)으로 인해, 모든 결합된 테이블은 그 다음에 아래와 같이 조인되어야 한다 :
TIME_SHEETS -> ASSIGNMENTS -> PROJECTS -> EMPLOYEES
순서화된 힌트(ORDERED hint)
ORDERED hint는 언제나 동작한다. 그러나, 시스템은 조인 기준이 조인의 순서에 허용되는 경우에 보다 효율적이다. 종종, 이는 현재의 조인 기준에서의 이행성에 대응하는 조인 기준을 부가하는 것을 의미하기도 한다.
조인 순서를 선택하는 경우, 시스템은 명백한 조인 기준이 존재하는지의 여부를 검사해야 한다. 만일 존재하지 않으면, 시스템은 조인 기준이 내포된 이행성을 통해서 검사해야 한다. 내포된 조인 기준이 존재하면, 이 기준은 검사되기 이전에 질의에 부가되어야 한다. 파라미터들이 이미 ORDERED hint에 내포되어 있으므로, 내포된 조인 기준은 ORDERED hint에 계속해서 내포되어야 한다. 시스템은, 다른 최적화 모드들에 대하여 SQL 텍스트를 변경하는 것이 바람직하지 않으므로, 사용자가 ORDERED hint를 사용자 본의대로 사용할 수 있는 때에 조인 순서를 처리한다.
이하의 예에 있어서, 테이블 X1 및 X2 간에는 명백한 조인 기준이 존재하지 않더라도, 조인은 이행성을 통해서 존재한다. 검사 방법은 X1으로부터 X2로의 조인 경로를 따르는 것이다. 예를 들면, X1으로부터 S로에 대하여는, 그 조인이 "x1.emp_seq = s.emp_seq AND x1.coll = s.effective_date"이다. 또한, S로부터 E로는 그 조인이 EMP_SEQ 이후이다. 이는 분명히 "x.emp_seq = e.emp_seq"를 제공한다. 이어서 X2로의 경로를 따르면, E로부터 EMP_SEQ를 통해서 D로 진행한다. 따라서, 상기의 "x1.emp_seq = d.emp_seq"일 수 있다. 마지막으로, 경로는 D로부터 "d.emp_seq = x2.emp_seq AND d.effective_date = x2.coll"를 통해서 X2로 진행한다. 따라서, 경로는 결과적으로 "x1.emp_seq = x2.emp_seq"이다. ORDERED hint는 X2에 조인된 X2를 원하고, 명백한 조인 기준 "x1.emp_seq = x2.emp_seq"가 존재하므로, 기준은 파라미터로서 ORDERED에 부가되어야 한다.
X2와 X3 간의 이행성의 조인 기준을 얻기 위해서는 동일한 처리를 수행하여야 한다. 예를 들면, "x2.emp_seq = x3.emp_seq"이다. X3가 E에 명백하게 조인되지 않으므로, 시스템은 조인 기준 "x3.emp_seq = e.emp_seq" 를 포함하여야 한다.
명백한 조인 기준과 함께 ORDERED hint에 대해 제안된 포맷은 다음과 같다 :
SELECT /*+ORDERED(xl, x2, x3, e, s, j, d, "xl.emp_seq = x2.emp_seq", "x2.emp_seq = x3.emp_seq", "x3.emp_seq = e.emp_seq")*/ e.emp_seq, e.lname, e.fname, s.sal, d.dept_seq, j.job_seq
FROM employees e, sal_history s, job_history j, dept_history d,
(SELECT emp_seq, MAX(effective_date) coll FROM sal_history
GROUP BY emp_seq) xl,
(SELECT emp_seq, MAX(effective date) coll FROM job_history
GROUP BY emp_seq) x2,
(SELECT emp_seq, MAX(effective_date) coll FROM dept_history
GROUP BY emp_seq) x3
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.emp_seq = xl .emp_seq
AND s.effective_date = xl.coll
AND j.emp_seq = x2.emp_seq
AND j.effective_date = x2.coll
AND d.emp_seq = x3.emp_seq
AND d.effective_date = x3.coll
FROM 절에서의 네스티드 선택(Nested Selects in FROM Clause)
네스티드 선택이 FROM 절 내에 있고, 넌조인 기준 참조가 메인(main) SQL 모듈 내에 있으면, 시스템은 상기 기준을 네스티드 SELECT의 WHERE 절로 이동시키는지를 검사한다. 예를 들어,
SELECT * FROM employees e, (SELECT DISTINCT emp_seq, relation
FROM dependents d
WHERE birthdate > `01-jan-80') x
WHERE e.emp_seq = x.emp_seq
AND x.relation = `SPOUSE'
상기의 SQL 문장은
SELECT * FROM employees e, (SELECT DISTINCT emp_seq, relation
FROM dependents d
WHERE birthdate > `01-jan-80'
AND relation = `SPOUSE') x
WHERE e.emp_seq = x.emp_seq
로 변환될 수 있다.
이러한 경우에, 넌조인 기준은 부질의로 이동되어, 조인 이후에 필터링되기 이전에 한정된 로우의 수를 더 감소시키게 된다.
어떤 데이터베이스는 이미 이를 고려하였음에도 불구하고 WHERE 절에 기준을 이동시키는 것은 힌트들이 보다 용이하게 기술되도록 함과 함께 유익하게 된다는 점을 주목한다.
NOT 로직(NOT'ed Logic)
NOT 기준은 중요하지 않기 때문에 일반적으로 본 명세서에서는 최적화라는 용어로 간주되지 않는다. 즉, 데이터베이스는 전형적으로 NOT 기준을 전치시키는 것을 자동적으로 핸들링한다
NVL 함수
함수에 대한 디폴트 파라미터가 피연산자 상수와 동일하지 않으면, WHERE NVL(cost, 0) = 10은 NULL이 리턴되지 않은 경우에 WHERE 0 =10로 평가한다. 따라서, default(0)는 10과 동일하지 않으므로, NVL 함수는 생략될 수 있고, 따라서 기준에서 인덱스를 사용하는 것이 가능하게 된다. 기준에서 인덱스를 사용할 수 없다면, 어떤 것도 하지 않는다. 컬럼이 NULL 가능하지 않다면, NVL 함수일 이유가 없으므로 어떠한 것도 하지 않는다.
WHERE NVL(cost, 0) = 0은 다른 인덱스된 기준이 존재하지 않는다면 전치되지 않아야 한다. 예를 들어 만일 이것이 존재한다면, 시스템은 WHERE cost = 0 OR cost IS NULL로 전치되어야 할 것이다. 이는 다른 인덱스된 기준 없이 완전한 테이블 스캔을 요구하게 될 것이다. 예컨대, 아래의 예를 보자.
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq
AND e.hiredate = SYSDATE-7
AND NVL(d.birthdate, `01-JAN-80') = `01-JAN-80'
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq
AND e.hiredate = SYSDATE-7
AND (d.birthdate = `01-JAN-80' OR d.birthdate IS NULL)
로 변환될 수 있다.
그리고, 이는
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq
AND e.hiredate = SYSDATE-7
AND d.birthdate = `01-JAN-80'
UNION ALL
SELECT * FROM employees e, dependents d
WHERE e.emp_seq = d.emp_seq
AND e.hiredate = SYSDATE-7
AND d.birthdate IS NULL
로 더 변환될 수 있다.
각각의 SQL 모듈(예를 들면, 각각의 네스티드 질의)을 개별적으로 최적화하는 것이 보다 더 가능하게 된다. 또한, 변환은 최하위 모듈에서 표준 부등을 포함하지 않는다는 점을 주목한다. OR가 동일한 컬럼에 존재하면, 이는 반드시 그럴 필요는 없다. OR 기준은 이하에 보다 상세히 논의된다.
OR 기준(OR'ed Criteria)
이하의 예들은 시스템이 OR 기준을 어떻게 핸들링하는지를 설명하는 것이다. 예를 들어,
select * from tab where A1 0 OR B20
상기의 SQL 문장은
select * from tab where (A = 10)
UNION ALL
Select from tab where (A != 10) AND (B = 20)
로 바꾸어 쓸 수 있다.
컬럼 A 및 B가 NULL일 수 있다면, 그 해결안은
select * from tab where (A = 10)
UNION ALL
select * from tab where (A != 10 OR A IS NULL) AND (B = 20)
이다.
where A = lO or (B = 2O AND C = 1)
와 같이 바꾸어 쓸 수 있는 WHERE 절은
WHERE A = 10
UNION ALL
WHERE A != 10 AND (B =20 AND C= 1)
로서 바꾸어 쓸 수 있다.
'IS NOT NULL'은 컬럼이 NULL일 수 있으면 부가되어야 하다.
새로운 플랜 오퍼레이션(New Plan Operation)
BITMAP KEY ITERATION(비트맵 키 반복)
이는 부질의가 복수의 값을 출력하여 비트맵 인덱스로 진행하는 경우에 발생된다. 만일 IN 등일 때도 검사하라. 이미 BITMAP OR은 비트맵 인덱스에 대한 IN 연산으로 복수의 값을 핸들링하였다.
그외의 힌트들(Other Hints)
데이터 웨어하우징(warehousing)에 있어서, 스타 스킴(star scheme)은 데이터 웨어하우스에서의 기본(primary) 정보와 훨씬 적은 차원의 테이블(예컨대, 룩업(lookup) 테이블)을 포함하는 하나 이상의 매우 큰 사실(fact) 테이블을 나타내는 데 사용되는데, 상술된 훨씬 적은 차원의 테이블들 각각은 사실 테이블의 특정 속성에 대한 엔트리들에 대한 정보를 포함한다.
스타 질의는 사실 테이블과 복수의 룩업 테이블 간의 조인이다. 각각의 룩업 테이블은 기본 키를 사용하여 사실을 외국인 키 조인에 조인된다. 그러나, 룩업 테이블들은 서로 조인되지 않는다.
스타 변환은 실행 중인 스타 질의에서 효율적으로 달성하고자 하는 비용 기반의 질의 변환이다. 스타 최적화가 적은 수의 차원 및 조밀한 사실 테이블을 이용하는 방안에 대해서 양호하게 동작할 수 있는 것에 반하여, 스타 변환은 이하의 것 중 어느 하나가 참일지라도 대체예로서 간주될 수 있다. 예를 들면, 스타 변환은, 사실 테이블들이 희박한 경우 또는 차원의 수가 큰 경우에 이용될 수 있다. 또한, 스타 변환은 술어(predicate)를 포함하는 모든 차원(dimension) 테이블이 갖는 질의가 있다면, 스타 변환은 유용하게 될 것이다. 스타 변환은 차원 테이블의 카테시안 프로덕트(Cartesian product)의 계산에 의존하지 않으므로, 이는 사실 테이블이 희박한 경우에 보다 바람직하게 적합하게 되고/되거나, 큰 값의 차원은 사실 테이블에서 실제로 거의 일치하지 않은 로우와 함께 큰 카테시안 프로덕트로 유도된다. 또한, 연쇄적인(concatenated) 인덱스에 의존하기 보다, 스타 변환은 각각의 사실 테이블 컬럼 상의 비트맵 인덱스를 결합하는 데 기초한다. 따라서, 변환은 제한된 차원에 정확히 대응하는 인덱스들을 합성할 수 있다. 서로 다른 컬럼 순서는 서로 다른 질의에서 서로 다른 패턴의 제한된 차원에 매칭된다.
"STAR_TRANSFORMATION"은 본 시스템이, 변환이 사용되는 가장 바람직한 플랜을 이용할 수 있게 한다. 이는 사실 테이블에 비트맵 인덱스가 존재하고, 차원 테이블에 대해서 충분한 기준이 있는 경우에 나타난다.
스타 변환은 소정의 특성을 가진 테이블에 대해서는 지원되지 않는다. 예를 들어, 다음과 같은 특성을 가진 테이블은 지원되지 않는다: 즉, 비트맵 액세스 경로와 호환 가능하지 않는 테이블 힌트를 갖는 테이블; 거의 비트맵 인덱스를 갖지 않는 테이블(최적화기가 부질의를 생성하도록 고려하도록 사실 테이블 컬럼에 대해 비트맵 인덱스가 존재하여야 함); 원격 테이블(그러나, 원격 차원 테이블은 생성되는 부질의들에 허용됨); 안티조인(anti-joined) 테이블; 부질의에서 차원 테이블로서 이미 사용된 테이블; 실제로 머지(merge)되지 않고, 뷰 파티션(partition)이 아닌 뷰인 테이블; 양호한 단일 테이블 액세스 경로를 갖는 테이블; 및 너무 작아서 변환될만하지 않는 테이블.
다음의 예는 질의에서 초기에 네스티드 선택의 결과를 감소시킨 것을 예시한다. 예를 들면, 사용자는 FROM 절에서 네스티드 선택을 가진 이하의 질의를 입력한다.
SELECT e.* FROM employees e, time_sheets t, projects p,
(SELECT emp_seq, MAX(effective_date) coll
FROM sal_history s
GROUP BY emp_seq) x
WHERE e.emp_seq = t.emp_seq
AND t.proj_seq = p.proj_seq
AND p.name = `PAFO'
AND t.emp_seq = x.emp_seq
AND t.rpt_date = x.coll
"AND x.coll < SYSDATE"
사용자는 이하에 예시된 바와 같이 네스티드 선택과 함께 기준을 두어야 한다. 즉, 네스티드 선택의 결과는 초기에 감소될 수 있다.
SELECT e.* FROM employees e, time_sheets t, projects p,
(SELECT emp_seq, MAX(effective_date) coll
FROM sal_history s
GROUP BY emp_seq
"HAVING MAX(effective_date) < SYSDATIE)" x
WHERE e.emp_seq = t.emp_seq
AND t.proj_seq = p.proj_seq
AND p.name = `PAFO'
AND t.emp_seq = x.emp_seq
AND t.rpt_date = x.coll
오브젝트_인스턴스(OBJECT_INSTANCE)
최적화 동안 테이블이 액세스되지 않으면, 시스템은 테이블이 SQL 문장에 있는지를 식별할 수 없게 된다. 예를 들어, 다음의 SQL 문장에서, ASSIGNMENTS와 PROJECTS는 둘 다 이들의 인덱스 액세스에 의해 ALL ROWS 모드에서만 표현된다. 즉, 테이블은 액세스될 필요가 없다. 따라서, 사용자가 ASSIGNMENTS에 대한 인덱스 오퍼레이션에 대해서 체크하면, SQL에는 플랜과 SQL 간의 관계를 식별하도록 하이라이트되는 것이 없다.
SELECT * FROM employees e,
(SELECT DISTINCT emp_seq FROM assignments a, projects p
WHERE a.proj_seq = p.proj_seq) x
WHERE e.emp_seq = x.emp_seq
시스템은 테이블이 전체 SQL 문장에서 유일한지를 적어도 체크해야 한다. 만일 유일하다면, 시스템은 사용자가 인덱스 오퍼레이션을 클릭한 경우에 그 테이블을 하이라이트해야 한다.
오브젝트 인스턴스(OBJECT INSTANCE)
FROM 절 내에 네스티드 선택이 있는 경우, 본 시스템은 네스티드 선택에 주어진 OBJECT_INSTANSE 값 뿐만 아니라 네스티드 선택 내부의 오브젝트에 주어진 OBJECT_INSTANSE 값을 고려하지 않는다.
대체 SQL(ALTERNATE SQL)
사용자가 FIRST ROWS 모드를 원하는 경우에, 부질의를 FROM 절로 이동시키는 것은 일반적으로 적절하지 않다. 머지하는 것이 항상 바람직하지만, 반드시 이동할 필요는 없다. 예를 들어 히스토리 데이터 질의를 살펴보자. 사실상, 상관된 부질의들을 남겨두거나 비상관을 상관으로 변환시킬 수도 있다.
원래 SQL이 특정된 것 외에 다른 조인 순서를 요청하는 ORDERED hint가 부가되는 경우에, 시스템은 FROM 절을 다시 조정하여, 이를 데이터베이스로 패스한다. 그러나, 시스템이 다시 조정하는 경우에, 원래의 ORDERED hint가 파라미터와 함께나타나게 된다. 파라미터가 실제의 힌트 구문(syntax)의 일부가 아니므로, 시스템은 SQL에 대한 HINTS 모드를 디스플레이할 대 ORDERED hint에 대한 파라미터를 생략한다. 예를 들어, 만일 EDIT 윈도우에 있는 원래의 SQL은 아래와 같으면,
SELECT /*+HINTl ORDERED(s, d ,e ,j) */*
FROM employees e, sal_history s, job history j, dept history d
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.sal > 500
AND j.job_seq = 10
AND d.effective_date = j.effective_date
AND s.effective_date = j.effective_date
HINTS 1 윈도우는 다음과 같이 디스플레이되어야 한다 :
SELECT /*+ORDERED */*
FROM sal_history s , dept history d, employees e, job_history j
WHERE e.emp_seq = s.emp_seq
AND e.emp_seq = j.emp_seq
AND e.emp_seq = d.emp_seq
AND s.sal > 500
AND j.job_seq = 10
AND d.effective_date = j.effective_date
AND s.effective_date = j .effective_date
이는, FROM 절이 변경되는 것과 더불어, 키워드 HINTS1이 나타나지 않도록 하는 것과 일치되는 것이다. 즉, 특정 모드에 대한 SQL 윈도우는 데이터베이스에 패스되는 것을 정확하게 디스플레이하여야 한다. 이는 조인 기준이 ORDERED hint에 부가되는 경우에 수행되어야 한다.
REPORTS
유용한 보고는, "인덱스 컬럼 (단일 컬럼 인덱스)"이 히스토그램(histogram)을 생성하는 이득이 있다는 권고 중의 하나이다. 히스토그램이 일반적인 분포를 갖지 않는 컬럼으로만 구성되어야 하므로, 우리는 일반적인 분포를 갖지 않는 컬럼을 찾을 필요가 있다.
"HINTS" : ALL ROWS의 경우, "테이블에 조인된(joined to table)" 인덱스가 해당 테이블보다 크면, FULL로 한다.
SQL 체크(SQL Check)
부질의가 관계형 연산자 NOT IN 또는 모든 형태의 ALL과 인터페이스하는 경우에, 시스템은 다음의 메시지를 표시하고, 가능하다면 부질의를 하이라이트한다 :
"부질의가 어떤 로우도 리턴하지 않으면 (엠프티 셋트(empty set)이면), 부질의를 포함하는 기준은 TRUE로 평가된다. 즉, 부질의가 로우를 리턴하지 않으면 NOT EXISTS와 동일하도록 정확히 기능한다."
대체 SQL(ALTERNATE SQL)
부질의가, 동일 테이블을 참조하는 기준에 있는 컬럼을 리턴하면, 부질의의 선택 리스트는 대신에 ROWID를 포함하도록 변경되어야 한다. 예를 들어, 다음의 히스토리 질의를 살펴보면,
SELECT * FROM employees e, sal_history s1
WHERE e.emp_seq = s1.emp_seq
AND s1.effective_date =
(SELECT max(effective_date) FROM sal_history s2
WHERE e.emp_seq = s2.emp_seq
AND s2.effective_date < SYSDATE)
상기의 히스토리 질의는
SELECT * FROM employees e, sal_histoiy sl
WHERE e.emp_seq = sl.emp_seq
AND sl."ROWID" =
(SELECT "ROWID" FROM sal_history s2
WHERE e.emp_seq = s.emp_seq
AND s2.effective_date <= SYSDATE)
로 변환될 수 있다.
힌트(HINTS)
힌트가 적용되는 경우에, 사용자는 힌트가 영향을 미치는지의 여부를 살펴보며 작업해야 한다. 본 시스템은 사용자로 하여금 힌트가 영향을 미쳤는지를 알려주는 피드백을 제공할 수 있다. 예를 들어, 시스템은 ORDERED hint가 소정의 순서로 조인되었는지의 여부를 사용자에게 알려줄 수 있다.
NOT IN 또는 NOT EXISTS 부질의를 포함하는 질의의 경우, 이해성은 그 상황의 질의에 있는 인터페이스 컬럼들은 동일한 테이블에 속하도록 적용될 수 있다. 이는, 테이블이 하나 이상의 테이블에 아웃터 조인될 수 없으므로, NOT IN 및 NOT EXISTS 부질의를 머지하게 한다.
예를 들면,
SELECT *
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND (e.emp_seq, a.start_date) NOT IN (SELECT emp_seq, rpt_date
FROM time_sheets)
상기의 SQL 문장은
SELECT *
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND (a.emp_seq, a.start_date) NOT IN (SELECT emp_seq, rpt_date
FROM time sheets)
로 변환될 수 있고, 상기의 문장은
SELECT e.*, a.*
FROM employees e, assignments a time_sheets ti
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t1.emp_seq(+)
AND a.start_date = ti.rpt_date(+)
AND t1.ROWID IS NULL
로 변환될 수 있다.
다음의 예는 조인시키기 위해 NOT IN 및 NOT EXISTS 부질의를 머지시키는 것을 예시한다. 예를 들어,
SELECT *
FROM employees e
WHERE NOT EXISTS
(SELECT *
FROM assignments a
WHERE e.emp_seq = a.emp_seq)
상기의 SQL 문장은
SELECT /*+ALL_ROWS*/e.*
FROM employees e,
(SELECT DISTINCT 1 col2 , a.emp_seq coll
FROM assignments a)
t1
WHERE e.emp_seq = tl.coll(+)
AND tl.col2 IS NULL
로 변환될 수 있다.
그러나, 부질의는 다음과 같이 머지되어야 한다.
SELECT e.*
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq(+)
AND a.emp_seq IS NULL
시스템은, 주위 인터페이스 컬럼에 있는 상수(constant)를 부질의로 이동시킴으로써 SQL 4를 SQL 5로 변환하고 나서 SQL 6으로 변환시킬 수 있다.
예를 들어,
SELECT *
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND (e.emp_seq, `22-FEB-94') NOT TN (SELECT emp_seq, rpt_date
FROM time_sheets)
SQL4
상기의 SQL 문장은
SELECT *
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND e.emp_seq NOT IN (SELECT emp seq
FROM time_sheets
WHERE rpt date = `22-FEB-94')
SQL5
로 변환될 수 있고, 상기의 문장은
SELECT e.*, a.*
FROM employees e, assignments a, time_sheets t1
WHERE e.emp_seq = a.emp_seq
AND a.emp_seq = t1.emp_seq(+)
AND t1.rpt_date(+) = `22-FEB-94'
AND t1.ROWID IS NULL
SQL6
로 변환될 수 있다.
다음의 질의는 머지된 경우에 부질의 테이블이 하나의 테이블로 아웃터 조인되어야 하기 때문에 변환될 수 없다.
SELECT *
FROM employees e, assignments a
WHERE e.emp_seq = a.emp_seq
AND `22-FEB-94' NOT IN (SELECT rpt_date
FROM time_sheets)
SQL 7
만일 부질의 인터페이스 컬럼이 상수이면, 조인된 경우에 모든 테이블이 유일하게 되면 머지가 수행될 수 있다. 부질의를 머지하는 경우에, 상수 Θ는 대응하는 주위 인터페이스 컬럼 및 '<child>.ROWID IS NULL'와 함께 OR 연산된 NOT EQUALS로 설정된다.
예를 들어,
SELECT *
FROM employees e
WHERE (e.emp_seq, lname) NOT IN (SELECT emp_seq. `SMITH'
FROM time_sheets
WHERE proj_seq = 1
AND rpt_date = `22-feb-94')
SQL 8
상기의 SQL 문장은
SELECT e.*
FROM employees e, time_sheets tl
WHERE e.emp_seq = t1.emp_seq(+)
AND proj_seq(+) = 1
AND rpt_date(+) = `22-feb-94'
AND (t1.ROWID IS NULL
OR lname <> `SMITH')
SQL9
로 변환될 수 있다.
SQL 문장을 변환하려는 경우에는 주의하여 시험하여야 한다. 예를 들어, 다음의 SQL 문장,
SELECT *
FROM employees e
WHERE emp_seq NOT IN (SELECT a.emp_seq
FROM projects p, assigmnents a
WHERE a.proj_seq = p.proj_seq
AND p.name = `EXPLAIN SQL: DEVELOPMENT')
ORDER BY I
을 다음의 문장
SELECT /*+ ALL_ROWS */
e.*
FROM employees e, projects p, assignments a
WHERE e.emp_seq = a.emp_seq(+)
AND a.proj_seq = p.proj_seq(+)
AND p.name(+) = `EXPLAIN SQL: DEVELOPMENT'
AND p.ROWID IS NULL
ORDER BY 1
으로 변환하는 시도가 가능하다.
그러나, 여기에서 원래의 SQL 문장을 아웃터 질의에 머지시키는 것이 가능하지 않기 때문에 이는 정확하지 않을 수 있다. 이는 부정확한 변환을 초래할 수 있다.
시스템이 임의의 테이블과 함께 'ROWID IS NULL'을 부가하려 하는 경우에 또 다른 문제가 발생할 수 있다. 예를 들면, 시스템은 FROM 절에 있는 순서에 따라서, 종종 프로젝트 테이블을 선택하기도 하고, 종종 할당 테이블을 선택하기도 한다. 최하위 레벨의 자식 테이블이 널 (예컨대, 프로젝트 테이블)인지를 확실히 하도록 주의하여 시험할 필요가 있다. 그렇지 않으면, 자식 테이블에 대한 조인 기준이 타당하지 않게 된다.
다음의 규칙과 지침은 변환 시에 지켜져야 한다.
A) 본 시스템은 다음의 경우에만 변환되어야 한다.
ⅰ) 조인 순서에 있는 모든 중간 테이블은 유일성을 보장하도록 조인되어야 한다.
ⅱ) 하나 이상의 분기(branch)가 있을 수 있다. 그러나, 많아야 하나의 최하위 레벨의 자식 테이블이 비유일(non-unique)일 수 있다. 다른 모든 테이블은 순서대로 조인될 때 유일하여야 한다. 즉, 상기의 SQL을 체크할 때, 할당 테이블은 인터페이스하는 부질의 컬럼을 갖는 테이블이다. 이것이 최하위 레벨의 자식이아니므로 (프로젝트 테이블은 이에 조인된다), = 연산자를 갖는 상수를 가진 where 절 조인 또는 선택 리스트에 있는 해당 컬럼들은 유일한 키를 형성해야 한다. 그러나, emp_seq는 유일한 컬럼이 아니다. 그래서, 이러한 부질의는 머지될 수 없다. 그러나, 이하의 예 SQL 10은 프로젝트 명이 유일한 컬럼인 경우에 변환될 수 있다.
ⅲ) 만일 부질의 인터페이스 컬럼들 중 하나가 상수이면, 모든 테이블은 유일성을 보장하기 위해서 조인되어야 한다.
ⅳ) 애그리게이트 함수는 존재하지 않는다 (GROUP BY, DISTINCT, 및 HAVING은 애그리게이트가 아닌 한 좋다. 머지되는 경우에, GROUP BY와 DISTINCT는 무시하고, HAVING 기준을 WHERE 절로 이동시킨다.)
ⅴ) CONNECT BY 구문이 존재하지 않는다.
ⅵ) 집합(set) 연산(예를 들면, UNION, MINUS)은 존재하지 않는다.
ⅶ) 부질의는 아웃터 조인을 포함하지 않는다.
B) 각각의 하위 레벨의 자식의 경우, '<child>.ROWID IS NULL' 및 OR를 함께 부가한다.
C) 주위 인터페이스 컬럼에 상수가 존재하고, 다른 인터페이스 컬럼들이 존재하면, 이를 부질의 where 절에 대한 상등 기준으로 변경시킨다.
D) 부질의 인터페이스 컬럼에 상수가 존재하면, 그 상수를, 대응하는 주위 인터페이스 컬럼에 대한 NOT EQUALS로 설정하고, 이를 '<child>.ROWID IS NULL'과 함께 OR 연산시킨다.
SELECT *
FROM status_list
WHERE status NOT IN (SELECT p.status
FROM projects p, assignments a
WHERE a.proj_seq = p.proj_seq
AND p.name = `EXPLAIN SQL: DEVELOPMENT')
SQL10
아웃터 조인이 발생할 수 있는지의 여부를 판정하는 경우에 상관 부질의는 문제를 초래할 수 있다. 보다 상세히는, NOT IN 연산자가 상관 부질의를 인터페이싱하는 경우에, 주위 질의에 있는 인터페이스 컬럼들은 부질의에 상관된 테이블과 동일한 테이블에 속하여야 한다. 예를 들어, 바로 아래에 있는 SQL 문장을 보라. 부질의에 있는 인터페이스 컬럼들은 부질의에 상관된 테이블과 동일한 테이블에 속하여야 한다. 아래의 예에서, HIREDATE 컬럼은 상관 기준 중 하나 뿐만 아니라 "e."에 속하지만 다른 상관 기준은 "a."를 참조한다. 따라서, 머지는 가능하지 않다.
SELECT * FROM time_sheets t
WHERE t.rpt_date NOT IN
(SELECT hiredate FROM employees e, assignments a
WHERE a.proj_seq = t.proj_seq
AND e.emp_seq = a.emp_seq
AND e.emp_seq = t.emp_seq)
SQL 11
상술된 규칙/지침 a)ⅰ) 및 a)ⅱ)가 ture인 한, "[NOT IN] 부질의에 있는 인터페이스 컬럼들은 상기 부질의에 상관된 테이블과 동일한 테이블에 속하여야 한다"는 것은 필수가 아니다. 그러나, 주위 질의에 있는 대응하는 인터페이스 컬럼은 아웃터 조인으로 인해 동일한 테이블에 속하여야 한다. 변환되면, 할당 테이블은 time_sheets 및 employees 둘 다에 아웃터 조인될 필요가 있다. 이는 적법하지 않다. 그러나, 이행성은 상술된 SQL 11 문장을 후술된 SQL 12 문장으로 변환되도록 적용될 수 있다. 다음으로, SQL 12는 후술되는 바와 같이 SQL 13으로 머지될 수 있다. employees 및 assignments 둘 다 인터페이스 컬럼(들)에 대하여 유일한 인덱스를 갖기 때문에, 머지 연산이 가능하다.
SELECT * FROM time_sheets t
WHERE t.ipt_date NOT IN
(SELECT hiredate FROM employees e, assignments a
WHERE a.proj_seq = t.proj_seq
AND t.emp_seq = a.emp_seq
AND e.emp_seq = t.emp_seq)
SQL12
SELECT * FROM time_sheets t, employees e, assignments a
WHERE e.hiredate(+) = t.rpt_date
AND a.proj_seq(+) = t.proj_seq
AND a.emp_seq(+) = t.emp_seq
AND e.emp_seq(+) = t.emp_seq
AND (a.rowid IS NULL or e.rowid IS NULL)
SQL13
또한, 부질의 선택 절에 있어서 넌컬럼(상수, 함수 등)을 가진 NOT EXISTS OR NOT IN 부질의를 머지할 수 없다는 점을 주의해야 한다. 예를 들면, 다음의 SQL 14를 SQL 15로 변환하는 시도가 있을 수 있다. 그러나, SQL 15는t.rtp_date = '22-FEB-94'로 인해 SQL 14와 동일한 결과를 생성하지 않는다. 기준은t.rtp_date <> '22-FEB-94'으로 변경될 수 있다. 그러나, 원래의 부질의가 적어도 하나의 로우를 리턴하도록 보장할 필요가 있다. 이는 부질의를 유지해야 하기 때문에 변환의 목적을 무효로 하는 것이다.
SELECT *
FROM time_sheets t
WHERE (t.emp_seq, t.rpt date) NOT IN (SELECT emp_seq, `22-FEB-94'
FROM employees)
SQL 14
SELECT /*+ ALL_ROWS */
t.*
FROM time_sheets t, employees t1
WHERE t.emp_seq = t1.emp_seq(+)
AND t.rpt_date = `22-FEB-94'
AND tl.ROWID IS NULL
SQL15
Set_NOT_IN_NOT_EXISTS_Subquery_Can_Be_Query
만일 연산자가 NOT IN 또는 NOT EXISTS이면, 다음의 루틴은 부질의를 조인으로 변환하려고 시도하여야 하는지의 여부를 결정하려는 시도가 호출될 수 있다.
<<code begin>>
IF subquery contains aggregate in Select list OR subquery contains aggregate in
HAViNG clause OR subquery contains Connect By syntax OR subquery contains set
operation THEN RETURN FALSE
LOOP over each table X in the FROM list, if there is more than 1 join criterion, apply
transitivity so the table join to the same table, if possible.
Initialize Unique_list to empty
Non_Unqiue_table := null
LOOP over each TABLE in the FROM list containing interface columns
IF CheckTableUniquelndexCols retum TRUE
(CheckTableUniquelndexCols routine checks for a given table, whether
all the columns of its any one unique indexes are present in the where
clause and have a `=` operation and the other operand is a constant or
a correlated.)
THEN add TABLE to the Unique_list
ELSE
IF Non Unqiue_table is null
THEN
Non_Unqiue table = TABLE
ELSE
RETURN FALSE
END LOOP over each TABLE in the FROM list containing interface columns
LOOP over each TABLE in the FROM list containing interface columns
IF Check_Unique(TABLE, interface table of the surrounding query, Unique_list, Non Unique table) returns FALSE
RETURN FALSE
END LOOP over each table in the FROM list containing interface columns
(Make sure all table is joined)
LOOP over each TABLE
IF TABLE not in unique list and TABLE <> Non_unique table
THEN
RETURN FALSE
END LOOP over each TABLE
RETURN TRUE
<<code end>>
Check Unique
Input:
TABLE
PARENT_TABLE
NONUNIQUE TABLE
<<code begin>>
LOOP over each table Y joined to TABLE
IF Y = PARENT_TABLE
continue loop
IF Y is in Unique_list or Y is Non_unique_table (if Y is already joined,
cannot join to another table)
THEN RETURN FALSE
LOOP over each index of Y
IF all indexed columns are joined to X with = operator OR index columns = constant
THEN
add Y to Unique_list
IF Check_Unique (Y, X, Unique_list, Non_unique_table) returns
FALSE
THEN RETURN FALSE
BREAK (unique index found, no need to search anymore)
END LOOP over each index of Y
IF Y not in Unique list
IF Non_unique_table is null
Non_unique table = Y
(Since Y is not unique, make sure no other table is joined to Y)
LOOP over each table Z joined to Y
IF Z not in Unique_list and Z <> Non_unique_table
THEN RETURN FALSE
END LOOP over each table Z joined to Y
ELSE
RETURN FALSE
END LOOP over each table Y joined to TABLE
RETURN TRUE
<<code end>>
만일 WHERE 절 기준이 FROM 절에 있는 네스티드 선택에서의 테이블을 참조하기만 한다면, 이를 네스티드 선택으로 이동시킨다.
예를 들면,
SELECT *
FROM employees e,
(SELECT DISTINCT emp seq, relation
FROM dependents d
WHERE birthdate > `01-jan-80') x
WHERE e.emp_seq = x.emp_seq
AND x.relation = `SPOUSE'
상기의 SQL 문장을
SELECT *
FROM employees e,
(SELECT DISTINCT emp_seq, relation
FROM dependents d
WHERE birthdate > `01-jan-80'
AND x.relation = `SPOUSE') x
WHERE e.emp_seq = x.emp_seq
로 변환할 수 있다.
만일 HAVING 절 기준이 그룹(group) 함수를 포함하지 않으면, WHERE 절로 이동될 수 있다.
예를 들어,
SELECT LNAME, count(*)
FROM employees
GROUP BY LNAME
HAVING LNAME < `D'
상기의 SQL 문장은
SELECT LNAML, count(*)
FROM employees
WHERE LNAME < `D'
GROUP BY LNAME
로 변환될 수 있다.
본 개시는 본 발명에서의 원리에 따라서 프로그램된 하나 이상의 상용의 범용 디지털 컴퓨터 및/또는 서버를 이용하여 편리하게 구현될 수 있다. 적절한 소프트웨어 코딩은 본 명세서에 개시된 원리에 기초하여 용이하게 작성될 수 있다.
또한, 상술된 설명은 특정 데이터베이스 시스템(예를 들면, 오라클)을 참고로 하였지만, 본 개시는 임의의 특정 데이터베이스 또는 임의의 특정 타입의 데이터베이스 시스템에 한정되지 않는다는 것을 유의해야 한다.
본 개시에 대한 다양한 추가의 변형 및 변경이 상술된 원리의 견지에서 가능하다. 그러므로, 첨부된 특허청구범위의 범주 내에서 본 개시가 본 명세서에서 특별히 기술된 바와 다른 것을 실시할 수도 있음을 이해하여야 한다.

Claims (33)

  1. 데이터베이스 질의(database query)를 조정(tuning)하는 방법에 있어서,
    데이터베이스 질의를 선택하는 단계;
    상기 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해 상기 선택된 데이터베이스 질의를 파싱(parsing)하는 단계;
    복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택하는 단계;
    상기 결정된 관계 및 상기 선택된 최적화 모드에 기초하여 상기 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써 상기 선택된 데이터베이스 질의를 조정하는 단계; 및
    상기 수정된 데이터베이스 질의를 표시(displaying)하는 단계
    를 포함하는 방법.
  2. 제1항에 있어서,
    상기 파싱 단계에서는 상기 데이터베이스 질의 내에서 토큰(token)을 결정하고, 상기 토큰은 구획 문자(delimiter)에 의해 분리된 워드(word)인 방법.
  3. 제1항에 있어서,
    상기 복수의 사용 가능한 최적화 모드는 비용 기반 및 규칙 기반 모드를 포함하는 방법.
  4. 제3항에 있어서,
    상기 비용 기반 모드는 First_Rows 모드 및 All_Rows 모드를 포함하는 방법.
  5. 제1항에 있어서,
    상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용을 결정하는 단계
    를 더 포함하는 방법.
  6. 제5항에 있어서,
    상기 선택된 데이터베이스 질의를 사용하는 데 관련되는 비용을, 상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용과 비교하는 단계
    를 더 포함하는 방법.
  7. 제1항에 있어서,
    상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절(clause) 중 적어도 하나에 의해 조인(join)된 적어도 하나의 부질의(subquery)를 포함하는지의 여부를 결정하기 위해 상기 선택된 데이터베이스 질의를 파싱하는 단계
    를 더 포함하는 방법.
  8. 제7항에 있어서,
    상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절 중 적어도 하나를 포함하는지의 여부에 기초하여 조정할 때 사용될 프레퍼런스(preference)를 선택하도록 사용자에게 프롬프트(prompt)하는 단계
    를 더 포함하는 방법.
  9. 제8항에 있어서,
    상기 프레퍼런스는 NOT EXISTS 연산자로부터 NOT IN 연산자로의 변환 및 상기 선택된 데이터베이스 질의로부터 아웃터 조인(outer join)으로의 변환 중 적어도 하나의 변환을 사용자가 선택할 수 있게 하는 재작성(rewrite) 프레퍼런스를 포함하는 방법.
  10. 제8항에 있어서,
    상기 프레퍼런스는 ALL 연산자에 의해 조인된 부질의를 조인 또는 아웃터 조인으로 변환하도록 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 방법.
  11. 제8항에 있어서,
    상기 프레퍼런스는 NOT IN 연산자에 의해 조인된 부질의를 변환하기 위해 NOT EXISTS 연산자 및 아웃터 조인 중 적어도 하나를 사용할지의 여부를 사용자가선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 방법.
  12. 데이터베이스 질의를 조정하기 위한 컴퓨터 실행 가능 코드를 포함하는 컴퓨터 저장 매체에 있어서,
    사용자가 데이터베이스 질의를 선택할 수 있게 하는 컴퓨터 실행 가능 코드;
    상기 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해 상기 선택된 데이터베이스 질의를 파싱하는 컴퓨터 실행 가능 코드;
    사용자가 복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택할 수 있게 하는 컴퓨터 실행 가능 코드;
    상기 결정된 관계 및 상기 선택된 최적화 모드에 기초하여 상기 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써 상기 선택된 데이터베이스 질의를 조정하는 컴퓨터 실행 가능 코드; 및
    상기 수정된 데이터베이스 질의를 표시하는 컴퓨터 실행 가능 코드
    를 포함하는 컴퓨터 저장 매체.
  13. 제12항에 있어서,
    상기 파싱은 상기 데이터베이스 질의 내에서 토큰을 결정하고, 상기 토큰은 구획 문자에 의해 분리된 워드인 컴퓨터 저장 매체.
  14. 제12항에 있어서,
    상기 복수의 사용 가능한 최적화 모드는 비용 기반 및 규칙 기반 모드를 포함하는 컴퓨터 저장 매체.
  15. 제14항에 있어서,
    상기 비용 기반 모드는 First_Rows 모드 및 All_Rows 모드를 포함하는 컴퓨터 저장 매체.
  16. 제12항에 있어서,
    상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용을 결정하는 코드
    를 더 포함하는 컴퓨터 저장 매체.
  17. 제16항에 있어서,
    상기 선택된 데이터베이스 질의를 사용하는 데 관련되는 비용을, 상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용과 비교하는 코드
    를 더 포함하는 컴퓨터 저장 매체.
  18. 제12항에 있어서,
    상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절 중 적어도 하나에 의해 조인된 적어도 하나의 부질의를 포함하는지의 여부를 결정하기 위해 상기 선택된 데이터베이스 질의를 파싱하는 코드
    를 더 포함하는 컴퓨터 저장 매체.
  19. 제18항에 있어서,
    상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절 중 적어도 하나를 포함하는지의 여부에 기초하여 조정할 때 사용될 프레퍼런스를 선택하도록 사용자에게 프롬프트하는 코드
    를 더 포함하는 컴퓨터 저장 매체.
  20. 제19항에 있어서,
    상기 프레퍼런스는 NOT EXISTS 연산자로부터 NOT IN 연산자로의 변환 및 상기 선택된 데이터베이스 질의로부터 아웃터 조인으로의 변환 중 적어도 하나의 변환을 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 컴퓨터 저장 매체.
  21. 제19항에 있어서,
    상기 프레퍼런스는 ALL 연산자에 의해 조인된 부질의를 조인 또는 아웃터 조인으로 변환하도록 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 컴퓨터 저장 매체.
  22. 제19항에 있어서,
    상기 프레퍼런스는 NOT IN 연산자에 의해 조인된 부질의를 변환하기 위해 NOT EXISTS 연산자와 아웃터 조인 중 적어도 하나를 사용할지의 여부를 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 컴퓨터 저장 매체.
  23. 데이터베이스 질의를 조정하기 위한 프로그램된 컴퓨터 시스템에 있어서,
    사용자에게 적어도 하나의 데이터베이스 질의를 표시하기 위한 표시기;
    상기 사용자가, 상기 표시된 데이터베이스 질의 중에서 한 데이터베이스 질의를 선택할 수 있게 하고, 복수의 사용 가능한 최적화 모드 중에서 한 최적화 모드를 선택할 수 있게 하는 사용자 입력; 및
    상기 선택된 데이터베이스 질의의 부분들 간의 관계를 결정하기 위해서 상기 선택된 데이터베이스 질의를 파싱하고, 상기 결정된 관계 및 상기 선택된 최적화 모드에 기초하여 상기 선택된 데이터베이스 질의 중 적어도 일부를 수정함으로써 상기 선택된 데이터베이스 질의를 조정하기 위한 프로세서 - 상기 수정된 데이터베이스 질의는 상기 표시기를 통해 상기 사용자에게 표시됨 -
    를 포함하는 시스템.
  24. 제23항에 있어서,
    상기 파싱은 상기 데이터베이스 질의 내에서 토큰을 결정하고, 상기 토큰은 구획 문자에 의해 분리된 워드인 시스템.
  25. 제23항에 있어서,
    상기 복수의 사용 가능한 최적화 모드는 비용 기반 및 규칙 기반 모드를 포함하는 시스템.
  26. 제25항에 있어서,
    상기 비용 기반 모드는 First_Rows 모드 및 All_Rows 모드를 포함하는 시스템.
  27. 제23항에 있어서,
    상기 프로세서는 상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용을 결정하는 시스템.
  28. 제27항에 있어서,
    상기 프로세서는 상기 선택된 데이터베이스 질의를 사용하는 데 관련되는 비용을, 상기 조정된 데이터베이스 질의를 사용하는 데 관련되는 비용과 비교하는 시스템.
  29. 제23항에 있어서,
    상기 프로세서는 상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절중 적어도 하나에 의해 조인된 적어도 하나의 부질의를 포함하는지의 여부를 결정하기 위해 상기 선택된 데이터베이스 질의를 파싱하는 시스템.
  30. 제29항에 있어서,
    상기 프로세서는 상기 데이터베이스 질의가 NOT EXISTS, NOT IN, 및 ALL 절 중 적어도 하나를 포함하는지의 여부에 기초하여 조정할 때 사용될 프레퍼런스를 선택하도록 사용자에게 프롬프트하는 시스템.
  31. 제30항에 있어서,
    상기 프레퍼런스는 NOT EXISTS 연산자로부터 NOT IN 연산자로의 변환 및 상기 선택된 데이터베이스 질의로부터 아웃터 조인으로의 변환 중 적어도 하나의 변환을 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 시스템.
  32. 제30항에 있어서,
    상기 프레퍼런스는 ALL 연산자에 의해 조인된 부질의를 조인 또는 아웃터 조인으로 변환하도록 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 시스템.
  33. 제30항에 있어서,
    상기 프레퍼런스는 NOT IN 연산자에 의해 조인된 부질의를 변환하기 위해NOT EXISTS 연산자와 아웃터 조인 중 적어도 하나를 사용할지의 여부를 사용자가 선택할 수 있게 하는 재작성 프레퍼런스를 포함하는 시스템.
KR1020027016062A 2000-05-26 2001-05-25 데이터베이스 질의를 자동으로 생성하는 시스템 및 방법 KR20030047889A (ko)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US20737900P 2000-05-26 2000-05-26
US60/207,379 2000-05-26

Publications (1)

Publication Number Publication Date
KR20030047889A true KR20030047889A (ko) 2003-06-18

Family

ID=22770299

Family Applications (1)

Application Number Title Priority Date Filing Date
KR1020027016062A KR20030047889A (ko) 2000-05-26 2001-05-25 데이터베이스 질의를 자동으로 생성하는 시스템 및 방법

Country Status (10)

Country Link
US (1) US8019750B2 (ko)
EP (1) EP1350184B1 (ko)
JP (1) JP2004509382A (ko)
KR (1) KR20030047889A (ko)
CN (1) CN1592905A (ko)
AU (2) AU6504801A (ko)
BR (1) BR0111192A (ko)
CA (1) CA2409276A1 (ko)
IL (2) IL152987A0 (ko)
WO (1) WO2001093105A2 (ko)

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7245080B2 (en) 2003-12-30 2007-07-17 Lg.Philips Lcd Co., Ltd. Substrate having organic electroluminescent device and method of fabricating the same
KR101432700B1 (ko) * 2012-10-10 2014-08-25 (주)티베로 쿼리의 최적화를 위한 방법

Families Citing this family (66)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8910241B2 (en) * 2002-04-25 2014-12-09 Citrix Systems, Inc. Computer security system
US7805411B2 (en) 2003-09-06 2010-09-28 Oracle International Corporation Auto-tuning SQL statements
US7587394B2 (en) * 2003-09-23 2009-09-08 International Business Machines Corporation Methods and apparatus for query rewrite with auxiliary attributes in query processing operations
US7343367B2 (en) * 2005-05-12 2008-03-11 International Business Machines Corporation Optimizing a database query that returns a predetermined number of rows using a generated optimized access plan
US20070143246A1 (en) * 2005-12-15 2007-06-21 International Business Machines Corporation Method and apparatus for analyzing the effect of different execution parameters on the performance of a database query
US7882121B2 (en) * 2006-01-27 2011-02-01 Microsoft Corporation Generating queries using cardinality constraints
US7702658B2 (en) * 2006-01-27 2010-04-20 International Business Machines Corporation Method for optimistic locking using SQL select, update, delete, and insert statements
US8903763B2 (en) * 2006-02-21 2014-12-02 International Business Machines Corporation Method, system, and program product for transferring document attributes
CN100403314C (zh) * 2006-04-19 2008-07-16 华为技术有限公司 一种数据查询方法
CN101093493B (zh) * 2006-06-23 2011-08-31 国际商业机器公司 数据库查询语言转换方法、转换装置
US20080040334A1 (en) * 2006-08-09 2008-02-14 Gad Haber Operation of Relational Database Optimizers by Inserting Redundant Sub-Queries in Complex Queries
US8694524B1 (en) * 2006-08-28 2014-04-08 Teradata Us, Inc. Parsing a query
US20080126393A1 (en) * 2006-11-29 2008-05-29 Bossman Patrick D Computer program product and system for annotating a problem sql statement for improved understanding
US8019771B2 (en) * 2006-11-30 2011-09-13 International Business Machines Corporation Method for dynamically finding relations between database tables
US10255583B2 (en) * 2007-05-01 2019-04-09 Oracle International Corporation Nested hierarchical rollups by level using a normalized table
CN100498793C (zh) * 2007-06-08 2009-06-10 北京神舟航天软件技术有限公司 用基于小波的压缩直方图实现二维谓词选择率估计的方法
US8065329B2 (en) * 2007-06-18 2011-11-22 Oracle International Corporation Query optimization on VPD protected columns
US8112421B2 (en) 2007-07-20 2012-02-07 Microsoft Corporation Query selection for effectively learning ranking functions
US7774318B2 (en) 2007-07-30 2010-08-10 Sap Ag Method and system for fast deletion of database information
US9009181B2 (en) * 2007-08-23 2015-04-14 International Business Machines Corporation Accessing objects in a service registry and repository
US7783656B2 (en) * 2007-09-24 2010-08-24 International Business Machines Corporation Accessing objects in a service registry and repository using a treat as function
US8903801B2 (en) 2007-09-14 2014-12-02 Oracle International Corporation Fully automated SQL tuning
US8600977B2 (en) * 2007-10-17 2013-12-03 Oracle International Corporation Automatic recognition and capture of SQL execution plans
US8516539B2 (en) * 2007-11-09 2013-08-20 Citrix Systems, Inc System and method for inferring access policies from access event records
US8990910B2 (en) * 2007-11-13 2015-03-24 Citrix Systems, Inc. System and method using globally unique identities
CN101436192B (zh) * 2007-11-16 2011-03-16 国际商业机器公司 用于优化针对垂直存储式数据库的查询的方法和设备
US7827153B2 (en) * 2007-12-19 2010-11-02 Sap Ag System and method to perform bulk operation database cleanup
US9240945B2 (en) * 2008-03-19 2016-01-19 Citrix Systems, Inc. Access, priority and bandwidth management based on application identity
US8943575B2 (en) * 2008-04-30 2015-01-27 Citrix Systems, Inc. Method and system for policy simulation
US8150865B2 (en) * 2008-07-29 2012-04-03 Oracle International Corporation Techniques for coalescing subqueries
US8990573B2 (en) * 2008-11-10 2015-03-24 Citrix Systems, Inc. System and method for using variable security tag location in network communications
US8065323B2 (en) * 2009-02-23 2011-11-22 Oracle International Corporation Offline validation of data in a database system for foreign key constraints
US8452754B2 (en) * 2009-05-08 2013-05-28 Microsoft Corporation Static analysis framework for database applications
US8555263B2 (en) * 2010-01-20 2013-10-08 Aetna Inc. System and method for code automation
US10311105B2 (en) * 2010-12-28 2019-06-04 Microsoft Technology Licensing, Llc Filtering queried data on data stores
US8880508B2 (en) * 2010-12-30 2014-11-04 Sap Se Processing database queries using format conversion
US8694525B2 (en) * 2011-06-24 2014-04-08 Sas Institute Inc. Systems and methods for performing index joins using auto generative queries
CN102968420B (zh) * 2011-08-31 2016-05-04 国际商业机器公司 数据库查询的方法和系统
GB2505183A (en) * 2012-08-21 2014-02-26 Ibm Discovering composite keys
US10726010B2 (en) * 2012-09-04 2020-07-28 Oracle International Corporation Optimization technique of generalized disjunctive semi/anti join
US10592506B1 (en) * 2013-02-13 2020-03-17 Amazon Technologies, Inc. Query hint specification
US9146984B1 (en) * 2013-03-15 2015-09-29 Google Inc. Enhancing queries for data tables with nested fields
US20150039555A1 (en) * 2013-08-02 2015-02-05 International Business Machines Corporation Heuristically modifying dbms environments using performance analytics
US10394807B2 (en) * 2013-11-27 2019-08-27 Paraccel Llc Rewrite constraints for database queries
US10621064B2 (en) 2014-07-07 2020-04-14 Oracle International Corporation Proactive impact measurement of database changes on production systems
US9779136B2 (en) * 2014-09-30 2017-10-03 Linkedin Corporation Rearranging search operators
CN104881460A (zh) * 2015-05-22 2015-09-02 国云科技股份有限公司 一种基于Oracle数据库实现多行数据并为一行显示的方法
US10229358B2 (en) * 2015-08-07 2019-03-12 International Business Machines Corporation Optimizer problem determination
CN106598963B (zh) * 2015-10-14 2021-08-10 五八同城信息技术有限公司 查询语句优化方法及装置
US10210223B2 (en) 2015-10-27 2019-02-19 International Business Machines Corporation Executing conditions with negation operators in analytical databases
US10558458B2 (en) * 2016-06-06 2020-02-11 Microsoft Technology Licensing, Llc Query optimizer for CPU utilization and code refactoring
KR101797483B1 (ko) 2016-07-19 2017-11-15 주식회사 티맥스데이터 데이터베이스 관리 시스템에서 쿼리를 프로세싱하기 위한 기법
CN106919678A (zh) * 2017-02-27 2017-07-04 武汉珞佳伟业科技有限公司 一种数据库查询优化系统及方法
US11386058B2 (en) 2017-09-29 2022-07-12 Oracle International Corporation Rule-based autonomous database cloud service framework
US11327932B2 (en) 2017-09-30 2022-05-10 Oracle International Corporation Autonomous multitenant database cloud service framework
US10354203B1 (en) * 2018-01-31 2019-07-16 Sentio Software, Llc Systems and methods for continuous active machine learning with document review quality monitoring
US10733187B2 (en) * 2018-02-09 2020-08-04 International Business Machines Corporation Transforming a scalar subquery
JP7044086B2 (ja) * 2019-03-15 2022-03-30 オムロン株式会社 制御システム、制御方法、および制御プログラム
US11100104B2 (en) * 2019-04-09 2021-08-24 Accenture Global Solutions Limited Query tuning utilizing optimizer hints
US11151131B2 (en) 2019-07-19 2021-10-19 Bank Of America Corporation Query generation from a natural language input
US11409744B2 (en) * 2019-08-01 2022-08-09 Thoughtspot, Inc. Query generation based on merger of subqueries
CN111209305B (zh) * 2019-11-19 2023-07-18 华为云计算技术有限公司 查询数据的方法、数据节点、分布式数据库、计算设备
US12032563B2 (en) 2020-04-14 2024-07-09 Capital One Services, Llc Database creation using table type information
CA3175498A1 (en) * 2020-04-14 2021-10-21 Dennis J. Mire Database creation using table type information
US11755579B2 (en) * 2021-08-04 2023-09-12 Cysiv, Inc. Database system with run-time query mode selection
US11847121B2 (en) 2021-08-27 2023-12-19 International Business Machines Corporation Compound predicate query statement transformation

Family Cites Families (21)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH022459A (ja) * 1987-12-11 1990-01-08 Hewlett Packard Co <Hp> 問合わせ処理方法
US5555409A (en) * 1990-12-04 1996-09-10 Applied Technical Sysytem, Inc. Data management systems and methods including creation of composite views of data
US5347653A (en) * 1991-06-28 1994-09-13 Digital Equipment Corporation System for reconstructing prior versions of indexes using records indicating changes between successive versions of the indexes
US5421008A (en) * 1991-11-08 1995-05-30 International Business Machines Corporation System for interactive graphical construction of a data base query and storing of the query object links as an object
US5404510A (en) * 1992-05-21 1995-04-04 Oracle Corporation Database index design based upon request importance and the reuse and modification of similar existing indexes
US6259896B1 (en) * 1994-02-15 2001-07-10 Nokia Mobile Phones Limited Device for radio communication
US5560007A (en) * 1993-06-30 1996-09-24 Borland International, Inc. B-tree key-range bit map index optimization of database queries
US5675785A (en) * 1994-10-04 1997-10-07 Hewlett-Packard Company Data warehouse which is accessed by a user using a schema of virtual tables
US5758145A (en) * 1995-02-24 1998-05-26 International Business Machines Corporation Method and apparatus for generating dynamic and hybrid sparse indices for workfiles used in SQL queries
US5806062A (en) * 1995-10-17 1998-09-08 Lucent Technologies Inc. Data analysis system using virtual databases
US5745904A (en) * 1996-01-12 1998-04-28 Microsoft Corporation Buffered table user index
US6061676A (en) * 1996-05-29 2000-05-09 Lucent Technologies Inc. Effecting constraint magic rewriting on a query with the multiset version of the relational algebric theta-semijoin operator
US5761654A (en) * 1996-06-05 1998-06-02 Oracle Corporation Memory structure and method for tuning a database statement using a join-tree data structure representation, including selectivity factors, of a master table and detail table
US5765168A (en) * 1996-08-09 1998-06-09 Digital Equipment Corporation Method for maintaining an index
US5765147A (en) * 1996-11-21 1998-06-09 International Business Machines Corportion Query rewrite for extended search capabilities
US5956707A (en) * 1997-02-13 1999-09-21 Chu; Wesley W. Database system with query relaxation using type abstraction hierarchy (TAH) as query condition relaxation structure
US6363377B1 (en) * 1998-07-30 2002-03-26 Sarnoff Corporation Search data processor
US6434545B1 (en) * 1998-12-16 2002-08-13 Microsoft Corporation Graphical query analyzer
US6205441B1 (en) * 1999-03-31 2001-03-20 Compaq Computer Corporation System and method for reducing compile time in a top down rule based system using rule heuristics based upon the predicted resulting data flow
EP1109117A1 (en) * 1999-12-14 2001-06-20 Sun Microsystems, Inc. Method for converting table data between a database representation and a representation in tag language
US7805411B2 (en) * 2003-09-06 2010-09-28 Oracle International Corporation Auto-tuning SQL statements

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7245080B2 (en) 2003-12-30 2007-07-17 Lg.Philips Lcd Co., Ltd. Substrate having organic electroluminescent device and method of fabricating the same
KR101432700B1 (ko) * 2012-10-10 2014-08-25 (주)티베로 쿼리의 최적화를 위한 방법

Also Published As

Publication number Publication date
IL152987A (en) 2009-05-04
BR0111192A (pt) 2005-05-10
WO2001093105A2 (en) 2001-12-06
EP1350184B1 (en) 2014-11-19
CN1592905A (zh) 2005-03-09
US8019750B2 (en) 2011-09-13
JP2004509382A (ja) 2004-03-25
IL152987A0 (en) 2003-06-24
EP1350184A2 (en) 2003-10-08
WO2001093105A3 (en) 2003-07-31
AU2001265048B2 (en) 2007-10-18
AU6504801A (en) 2001-12-11
US20070038618A1 (en) 2007-02-15
CA2409276A1 (en) 2001-12-06

Similar Documents

Publication Publication Date Title
AU2001265048B2 (en) System and method for automatically generating database queries
AU2001265048A1 (en) System and method for automatically generating database queries
US5615361A (en) Exploitation of uniqueness properties using a 1-tuple condition for the optimization of SQL queries
US5590324A (en) Optimization of SQL queries using universal quantifiers, set intersection, and max/min aggregation in the presence of nullable columns
US6529896B1 (en) Method of optimizing a query having an existi subquery and a not-exists subquery
US5761657A (en) Global optimization of correlated subqueries and exists predicates
US6032143A (en) Evaluation of existential and universal subquery in a relational database management system for increased efficiency
US5706494A (en) System and method for constraint checking bulk data in a database
US6338056B1 (en) Relational database extender that supports user-defined index types and user-defined search
US8965918B2 (en) Decomposed query conditions
US7734620B2 (en) Optimizing a database query that fetches N rows
US6167399A (en) Join index for relational databases
US6826562B1 (en) Method of simplifying and optimizing scalar subqueries and derived tables that return exactly or at most one tuple
EP0747839A1 (en) Database management system with improved indexed accessing
US20070061318A1 (en) System and method of data source agnostic querying
US20040019587A1 (en) Method and device for processing a query in a database management system
US7542962B2 (en) Information retrieval method for optimizing queries having maximum or minimum function aggregation predicates
US20060161515A1 (en) Apparatus and method for SQL distinct optimization in a computer database system
US6253196B1 (en) Generalized model for the exploitation of database indexes
US20040193567A1 (en) Apparatus and method for using a predefined database operation as a data source for a different database operation
US20080215539A1 (en) Data ordering for derived columns in a database system
Blakeley et al. Distributed/heterogeneous query processing in Microsoft SQL server
US8332373B1 (en) Representing user-defined routines with defined data structures
Yerneni Mediated query processing over autonomous data sources
Karayannidis et al. Design of the ERATOSTHENES OLAP Server

Legal Events

Date Code Title Description
WITN Application deemed withdrawn, e.g. because no request for examination was filed or no examination fee was paid