중화사전망 - 서예자전 - SQL 문 실행 흐름 및 정렬 원칙 분석
SQL 문 실행 흐름 및 정렬 원칙 분석
Oracle 문 실행 플로우
첫 번째 단계: 클라이언트는 실행을 위해 서버에 명령문을 보냅니다.
클라이언트에서 SQL 문을 실행하면 클라이언트는 서버의 프로세스가 명령문을 처리할 수 있도록 SQL 문을 서버로 보냅니다. 즉, Oracle 클라이언트는 아무 작업도 하지 않습니다. Oracle 클라이언트의 주요 작업은 클라이언트가 생성한 일부 SQL 문을 서버로 보내는 것입니다. 서버 프로세스가 사용자 프로세스에 대한 정보를 수신하면 필요한 메모리를 할당하고 관련 정보를 PGA 에 저장해야 합니다 (예: 세션 메모리에 관련 로그인 정보 저장).
클라이언트에도 데이터베이스 프로세스가 있지만 이 프로세스의 기능은 서버측 프로세스와는 달리 서버측 데이터베이스 프로세스가 SQL 문을 처리합니다. 그러나 한 가지 문제는 클라이언트의 프로세스와 서버의 프로세스가 일대일로 일치한다는 것이다. 즉, 클라이언트가 서버에 연결되면 클라이언트와 서버측에서 모두 하나의 프로세스가 형성됩니다. 우리는 클라이언트에서 클라이언트 프로세스라고 하고, 우리는 서버측에서 서버 프로세스라고 부른다.
두 번째 단계: 문장 분석
클라이언트가 SQL 문을 서버로 보내면 서버 프로세스가 명령문을 구문 분석합니다. 이 분석 작업은 서버측에서 진행되며, 해결 동작은 많은 작은 동작으로 나눌 수 있다.
1) 쿼리 캐시 (라이브러리 캐시)
서버 프로세스가 클라이언트로부터 SQL 문을 받을 때 데이터베이스를 직접 쿼리하지 않습니다. 서버 프로세스는 이 SQL 문의 문자를 ASCII 에 해당하는 숫자 코드로 변환한 다음 이 ASCII 코드를 해시 함수로 전달하고 해시 값을 반환합니다. 그런 다음 서버 프로세스는 공유 풀의 라이브러리 캐시 (캐시) 에 동일한 해시 값이 있는지 확인합니다. 있는 경우 공유 풀의 라이브러리 캐시에 이미 캐시된 해당 명령문의 분석 버전을 사용하여 서버 프로세스가 이를 수행하므로 후속 분석 작업이 절약됩니다. 이것은 소프트 분석입니다. 조정 캐시에 없는 경우 하드 구문 분석인 다음 단계가 필요합니다. 하드 구문 분석은 일반적으로 전체 SQL 실행 시간의 약 70% 를 차지하는 비용이 많이 드는 작업입니다. 하드 해결은 실행 트리, 실행 계획 등을 생성합니다.
따라서 데이터 캐시를 사용하면 SQL 문의 질의 효율성이 향상됩니다. 두 가지 이유가 있습니다. 한편으로는 하드 디스크의 데이터 파일에서 데이터를 읽는 것보다 메모리에서 데이터를 읽는 것이 더 효율적입니다. 반면에 문장 분석을 피하고 시간을 절약할 수 있다.
그러나 이러한 데이터 캐시는 일부 클라이언트 소프트웨어의 데이터 캐시와 다르다는 점에 유의해야 합니다. 쿼리 효율성을 높이기 위해 일부 클라이언트 소프트웨어는 애플리케이션 클라이언트에 데이터 캐시를 설정합니다. 이러한 데이터 캐싱을 통해 클라이언트 애플리케이션의 쿼리 효율성을 높일 수 있습니다. 그러나 다른 사람이 서버에서 관련 수정을 하면 응용 프로그램 데이터 캐시의 존재로 인해 수정된 데이터가 클라이언트에 제때에 반영되지 않습니다. 애플리케이션 소프트웨어의 데이터 캐시와 데이터베이스 서버의 캐시 데이터 캐시가 다르다는 것도 알 수 있다.
2) 데이터 사전 캐시.
캐시에서 해당 SQL 문을 찾을 수 없으면 서버 프로세스가 해당 명령문의 유효성을 검사하기 시작합니다. 여기에서는 주로 SQL 문의 구문을 검사하여 문법 규칙을 준수하는지 확인합니다. 서버 프로세스에서 이 SQL 문이 구문 규칙을 준수하지 않는다고 판단하면 이 오류 메시지가 클라이언트에 피드백됩니다. 이 문법 검사 과정에서 테이블 이름, 열 이름 등이 있다. SQL 문에 포함된 구문을 검사하지 않고 구문만 검사합니다.
3) 언어 의미 확인 (데이터 사전 캐시)
SQL 문이 구문 정의를 준수하는 경우 서버 프로세스는 문에 포함된 테이블, 인덱스, 뷰 및 기타 객체를 구문 분석하고 데이터 딕셔너리에 대해 이러한 객체의 이름 및 관련 구조를 검사하여 필드, 테이블, 뷰 등이 데이터베이스에 있는지 확인합니다. 테이블 및 열 이름이 정확하지 않으면 데이터베이스는 클라이언트에 오류 메시지를 피드백합니다.
따라서 select 문을 작성할 때 테이블 이름이나 열 이름 구문이 모두 잘못되면 구문 오류를 먼저 알리고 구문이 완전히 정확할 때까지 기다린 다음 열 이름이나 테이블 이름 오류를 묻는 메시지가 나타날 때가 있습니다.
4) 객체 해결 잠금 (제어 구조) 얻기
구문과 의미가 정확하면 조회해야 할 객체가 잠깁니다. 이는 주로 데이터의 일관성을 보장하기 위한 것으로, 조회 중 다른 사용자가 이 객체의 구조를 변경하지 못하도록 하기 위한 것입니다.
5) 데이터 액세스 확인 (데이터 사전 캐시)
구문과 의미가 검사를 통과하면 클라이언트가 데이터를 얻지 못할 수 있으며 서버 프로세스는 연결된 사용자가 해당 데이터에 액세스할 수 있는지 확인합니다. 사용자에게 데이터에 대한 액세스 권한이 없으면 클라이언트는 데이터를 얻을 수 없습니다. 데이터베이스 서버 프로세스는 액세스 권한을 확인하기 전에 구문과 의미를 확인합니다.
6) 최적의 실행 계획 결정
구문과 의미에 문제가 없고 권한이 일치하는 경우 서버 프로세스는 데이터베이스 파일을 직접 쿼리하지 않습니다. 서버 프로세스는 특정 규칙에 따라 명령문을 최적화합니다. 계획 개발 전에 뷰 병합, 하위 쿼리 중첩 해제, 술어 전달, 구체화된 뷰 재작성 쿼리 등과 같은 한 단계로 쿼리 변환이 이루어집니다. 사용할 실행 계획을 결정하기 위해 Oracle 은 테이블에 대한 액세스 접속 방법을 결정하고 가능한 최소 실행 계획을 결정하는 통계도 수집해야 합니다.
그러나 이러한 최적화는 제한적입니다. 일반적으로 응용 프로그램 소프트웨어 개발 과정에서 데이터베이스의 SQL 문을 최적화해야 하는데, 이 최적화는 서버 프로세스의 자체 최적화보다 훨씬 더 큰 역할을 합니다.
서버 프로세스의 최적기가 해당 질의문에 가장 적합한 실행 계획을 결정하면 SQL 문과 실행 계획을 데이터 캐시에 저장합니다. 이렇게 하면 나중에 이 쿼리가 있을 때 위의 구문, 의미, 권한 검사 단계를 생략하고 SQL 문을 직접 실행하여 SQL 문 처리의 효율성을 높일 수 있습니다.
단계 3: 바인드 변수 할당
SQL 문에서 바인드 변수를 사용하는 경우 바인드 변수의 선언을 스캔하고 바인드 변수에 값을 지정한 다음 변수 값을 실행 계획으로 가져옵니다. 구문 분석의 첫 번째 단계 캐시에 SQL 이 있는 경우 이 단계로 바로 이동합니다.
단계 4: 명령문 실행
문 구문 분석은 SQL 문의 구문만 구문 분석하여 서버가 이 문의 진정한 의미를 알 수 있도록 합니다. 명령문 구문 분석이 완료되면 데이터베이스 서버 프로세스가 실제로 SQL 문을 실행합니다.
SELECT 문의 경우:
1) 먼저 서버 프로세스는 필요한 데이터가 db 버퍼에 있는지 확인해야 합니다. 존재하고 사용할 수 있는 경우 데이터베이스 파일에서 데이터를 쿼리하는 대신 데이터를 직접 가져올 수 있으며 LRU 알고리즘에 따라 액세스 수를 늘릴 수 있습니다.
2) 데이터가 버퍼에 없는 경우 서버 프로세스는 데이터베이스 파일에서 관련 데이터를 쿼리하여 데이터 버퍼 캐시에 배치합니다.
여기서 데이터가 db 버퍼에 있는 경우 가용성 확인 방법은 db 버퍼 블록 헤더에 트랜잭션이 있는지 확인하고 트랜잭션이 있는 경우 롤백 세그먼트에서 데이터를 읽는 것입니다. 트랜잭션이 없는 경우 select 의 SCN 과 db 버퍼 블록 헤더의 SCN 을 비교하고, 이전 SCN 보다 작은 경우 롤백 세그먼트에서 데이터를 읽습니다. 전자가 후자보다 크면 더티 (dirty) 캐시가 아닌 경우 이 db 버퍼 블록의 내용을 직접 읽을 수 있습니다.
DML 문 (삽입, 삭제, 갱신) 의 경우:
1) 필요한 데이터베이스가 버퍼 캐시로 읽혀졌는지 확인합니다. 버퍼 캐시가 이미 있는 경우 3 단계로 직접 진행합니다.
2) 필요한 데이터베이스가 버퍼 캐시에 없는 경우 서버는 데이터 파일에서 버퍼 캐시로 데이터 블록을 읽습니다.
3) 수정할 테이블에 대해 행 배타적 잠금을 가져온 다음 수정할 데이터 행에 대해 배타적 잠금을 획득합니다.
4) 데이터의 리두 레코드를 리두 로그 버퍼에 복사합니다. 을 눌러 섹션을 인쇄할 수도 있습니다
5) 수정 된 데이터로 취소 데이터를 생성합니다.
6) dbbuffer 수정
7)dbwr 은 데이터 파일에 수정 사항을 기록합니다.
두 번째 단계에서 서버는 다음 단계를 수행하여 데이터 파일의 데이터를 데이터베이스 버퍼로 읽습니다.
1) 먼저 서버 프로세스는 헤더에서 TM 잠금을 요청합니다 (이 트랜잭션 실행 중 다른 사용자가 테이블의 구조를 수정할 수 없도록 보장). TM 잠금이 성공적으로 추가되면 일부 행 레벨 잠금 (TX 잠금) 이 요청됩니다. TM 과 TX 잠금이 모두 성공적으로 잠겨 있으면 데이터 파일에서 데이터를 읽습니다.
2) 데이터를 읽기 전에 읽은 파일을 위한 버퍼 공간을 준비합니다. 서버 프로세스는 LRU 목록에서 사용 가능한 데이터베이스 버퍼를 검색해야 합니다. 검색하는 동안 서버 프로세스는 더티 목록에 있는 수정된 모든 데이터베이스 버퍼를 등록합니다. 사용 가능한 db 버퍼 및 더티 (dirty) 블록 버퍼가 부족한 경우 dbwr 을 트리거하여 더티 (dirty) 버퍼에서 가리키는 버퍼 블록을 데이터 파일에 쓰고 이러한 버퍼를 정리하여 새로 읽은 데이터를 버퍼링할 공간을 확보합니다.
3) 충분한 여유 버퍼를 찾으면 서버 프로세스는 데이터 파일에서 해당 행이 있는 각 데이터 블록을 읽습니다. DB 블록은 ORACLE 의 최소 운영 단위입니다. 원하는 데이터가 DB 블록의 여러 행에 있는 하나 이상의 행일 뿐이더라도 ORACLE 은 이 DB 블록의 모든 행을 Oracle DB BUFFER 로 읽습니다. Db buffer 의 사용 가능한 영역 또는 돌출된 LRU 테이블의 더티 없는 블록 버퍼를 덮고 LRU 테이블의 머리에 배열합니다. 즉, db buffer 에 데이터 블록을 배치하기 전에 db buffer 에서 래치를 요청해야 합니다. 잠금에 성공한 경우에만 데이터를 db buffer 로 읽을 수 있습니다.
이 데이터 블록이 이미 db buffer cache (db buffer 또는 db cache 라고도 함) 에 있는 경우, db buffer 에서 트랜잭션이 없고 SCN 이 자체 더티 (dirty) 캐시 데이터 블록보다 작은 경우에도 서버 프로세스는 테이블 맨 위에서 레코드 잠금을 요청하며 잠금이 성공한 후에만 후속 작업을 수행할 수 있습니다. 성공하지 못하면 이전 프로세스가 잠금 해제될 때까지 기다렸다가 조치를 취해야 합니다 (이 경우 차단은 tx 잠금 차단임).
리두 로그를 기록할 때 다음 단계를 따릅니다.
1) 데이터는 db 버퍼로 읽혀지고, 서버 프로세스는 이 명령문의 영향을 받는 데이터 행의 rowid, 갱신할 원래 값과 새 값, SCN 등의 정보를 PGA 에서 리두 로그 버퍼까지 db 버퍼에 하나씩 기록합니다. 리두 로그 버퍼에 쓰기 전에 리두 로그 버퍼 잠금을 미리 요청하고 잠금이 성공한 후 쓰기를 시작해야 합니다.
2) 리두 로그 버퍼 크기의 1/3 에 도달하거나, 1M 에 도달하거나, 3 초 이상 쓰거나, 체크포인트 또는 dbwr 이 발생하기 전에 lgwr 프로세스가 리두 로그 버퍼의 데이터를 디스크의 리두 파일에 기록하도록 트리거합니다 (로그 파일 동기화 대기 이벤트 생성).
3) 리두 파일에 기록된 리두 로그 버퍼가 보유한 래치가 해제되고 후속 쓰기 정보로 덮어쓰여지며 리두 로그 버퍼가 재활용됩니다. 리두 파일도 재활용됩니다. 리두 파일이 가득 차면 lgwr 프로세스는 자동으로 다음 리두 파일로 전환합니다. 로그 파일 전환 (체크포인트 완료) 대기 이벤트가 발생할 수 있습니다. 아카이브 모드인 경우 아카이브 프로세스는 이전의 전체 리두 파일의 내용도 아카이브 로그 파일에 기록합니다. 이 경우 로그 파일 전환이 발생할 수 있습니다 (아카이브 필요).
거래에 대한 취소 정보를 설정할 때 구체적인 단계는 다음과 같습니다.
1) 이 트랜잭션과 관련된 리두 로그 버퍼가 완료되면 서버 프로세스는 이 db 버퍼의 블록 헤더에 있는 트랜잭션 목록을 재작성하기 시작하고 SCN 을 기록합니다 (처음에는 SCN 이 db 버퍼가 아닌 리두 로그 버퍼에 기록됩니다).
2) 그런 다음 이 블록의 헤더 트랜잭션 목록과 SCN 정보가 포함된 데이터 복제본을 롤백 세그먼트로 복사하여 롤백 세그먼트의 정보를 데이터 블록의 "전면 이미지" 로 호출합니다. 이' 전면 이미지' 는 향후 롤백, 복구 및 일관된 읽기에 사용됩니다. 롤백 세그먼트는 롤백 테이블스페이스 전용으로 하나 이상의 물리적 파일로 구성된 특수 롤백 테이블스페이스에 저장할 수 있습니다. 롤백 세그먼트는 다른 테이블스페이스의 데이터 파일에서도 열 수 있습니다. ).
데이터 파일에서 정보를 수정할 때 구체적인 단계는 다음과 같습니다.
1) db 버퍼 블록의 데이터 내용을 덮어쓰고 롤백 세그먼트의 주소를 블록 헤더에 기록합니다.
2) 데이터베이스 버퍼 포인터를 더티 목록에 놓습니다. 커밋되지 않고 데이터 행이 여러 번 업데이트되는 경우 롤백 세그먼트에 여러 개의 "전면 이미지" 가 있을 수 있습니다. 첫 번째' 전면 이미지' 에 SCN 정보가 포함된 것을 제외하고 각' 전면 이미지' 의 헤더에는 SCN 정보와 롤백 세그먼트의 주소가 포함되어 있습니다. 업데이트는 하나의 SCN 에만 해당하며 서버 프로세스는 dirty list 에 db 버퍼 블록에 대한 포인터를 설정합니다. 이렇게 하면 dbwr 프로세스가 dirty list 의 db 버퍼 블록을 찾아 데이터 파일에 쓸 수 있습니다. 그런 다음 서버 프로세스는 계속해서 데이터 파일에서 두 번째 데이터 블록을 읽고, 이전 블록의 동작을 반복하고, 데이터 블록을 읽고, 로그를 저장하고, 롤백 세그먼트를 설정하고, 데이터 블록을 수정하고, 더티 테이블에 배치합니다.
3) 더티 대기열 길이가 임계값 (일반적으로 25%) 에 도달하면 서버 프로세스는 dbwr 에 더티 데이터를 기록하도록 알립니다. 즉, db 버퍼의 래치를 해제하여 더 많은 유휴 DBBuffers 를 확보합니다. 사람들은 항상 Oracle 이 한 번에 하나의 데이터 블록을 읽는다고 말한다. 실제로 Oracle 은 한 번에 여러 개의 데이터 블록을 읽을 수 있습니다 (db_file_multiblock_read_count 는 한 번에 읽을 블록 수를 설정합니다).
제출을 수행할 때 구체적인 단계는 다음과 같습니다.
1)commit 는 lgwr 프로세스를 트리거하지만 dbwr 이 해당 db 버퍼 블록의 모든 잠금을 즉시 해제하도록 강제하지는 않습니다. 즉, 제출되었지만 dbwr 은 향후 일정 기간 동안 이 SQL 문에 관련된 데이터 블록을 쓰고 있을 수 있습니다. 헤더의 행 잠금은 제출 직후 해제되는 것이 아니라 dbwr 프로세스가 완료된 후 해제되므로 한 사용자가 다른 사용자가 제출한 리소스를 요청하지 못할 수 있습니다.
2) 제출과 dbwr 프로세스 종료 사이의 시간이 매우 짧습니다. 제출 후 dbwr 이 끝나기 전에 전원이 꺼지면 제출 후 데이터가 이미 데이터 파일의 내용에 속하기 때문에 이 파일 부분은 데이터 파일에 완전히 기록되지 않습니다. 그래서 너는 앞으로 굴러야 한다. Commit 은 이미 lgwr 을 트리거했기 때문에 이전에 데이터 파일에 기록되지 않았던 이러한 모든 변경 사항은 인스턴스 재시작 후 smon 프로세스에 의해 리두 로그 파일에 따라 롤포워드되어 이전 commit 에서 완료되지 않은 작업 (즉, 변경 사항을 데이터 파일에 기록) 을 완료합니다.
3) 제출 전에 전원이 꺼지면 db 버퍼의 데이터가 변경되었기 때문에 커밋되지 않았습니다. 즉, 이 데이터 부분은 데이터 파일에 속하지 않습니다. Lgwr 은 dbwr 이전에 트리거되기 때문에 데이터가 변경될 때마다 (로그가 있어야 함) dbwr 에서 데이터 파일에 수행한 모든 변경 사항이 리두 로그 파일에 먼저 기록됩니다. 인스턴스가 재시작되면 SMON 프로세스는 리두 로그 파일에 따라 앞뒤로 롤백됩니다.
실제로 smon 의 롤포워드와 롤백은 모두 체크포인트에 따라 수행됩니다. 전체 체크포인트가 발생하면 먼저 LGWR 프로세스가 redologbuffer 의 모든 버퍼 (커밋되지 않은 리두 정보 포함) 를 리두 로그 파일에 기록하도록 한 다음 dbwr 프로세스가 dbbuffer 의 커밋된 버퍼를 데이터 파일에 기록하도록 합니다 (커밋되지 않은 쓰기는 필수가 아님). 그런 다음 제어 파일과 데이터 파일 헤더의 SCN 을 업데이트하여 현재 데이터베이스가 일관성이 있음을 나타냅니다. 인접한 두 체크포인트 사이에 많은 트랜잭션이 있으며 커밋과 커밋되지 않은 트랜잭션이 있습니다.
롤백을 수행할 때 구체적인 단계는 다음과 같습니다.
서버 프로세스는 데이터 파일 블록 헤더 및 db buffer 에 있는 블록의 트랜잭션 목록 및 SCN 을 기준으로 롤백 세그먼트에서 수정 전 해당 복사본을 찾은 다음 이러한 원래 값을 사용하여 현재 데이터 파일에서 수정되었지만 커밋되지 않은 변경 사항을 복원합니다. 여러 개의' 전면 이미지' 가 있는 경우 서버 프로세스는 동일한 트랜잭션의 가장 오래된' 전면 이미지' 를 찾을 때까지' 전면 이미지' 의 시작 부분에서' 전면 이미지' 의 롤백 세그먼트 주소를 찾습니다. Commit 가 실행되면 사용자가 롤백할 수 없으므로 dbwr 프로세스가 commit 이후 완전히 완료되지 않은 후속 작업이 보장됩니다.
5 단계: 데이터 추출.
명령문 실행이 완료된 후에도 질의된 데이터는 서버 프로세스에 남아 있으며 클라이언트로 전송되는 사용자 프로세스가 없습니다. 따라서 서버측 프로세스에서 데이터 추출 전용 코드 조각이 있습니다. 그의 역할은 쿼리의 데이터 결과를 클라이언트 프로세스에 반환하여 전체 쿼리 작업을 완료하는 것입니다.
이 전체 쿼리 처리 프로세스를 보면 데이터베이스 개발 또는 애플리케이션 개발 과정에서 다음 사항에 유의해야 합니다.
첫째, 데이터베이스 캐시와 애플리케이션 소프트웨어 캐시가 서로 다르다는 것을 이해해야 한다. 데이터베이스 캐시는 데이터베이스 서버측에만 존재하며 클라이언트에는 존재하지 않습니다. 그래야만 데이터베이스 캐시의 내용이 데이터베이스 파일의 내용과 일치할 수 있습니다. 관련 규칙에 따라서만 더러운 읽기와 잘못된 데이터 읽기를 막을 수 있다. 그러나 애플리케이션 소프트웨어에 포함된 데이터 캐시는 데이터베이스 캐시와 동일하지 않습니다. 따라서 응용 프로그램의 데이터 캐싱은 데이터 쿼리의 효율성을 향상시킬 수 있지만 데이터 일관성의 요구 사항을 깨고 때때로 더러운 읽기와 잘못된 읽기가 발생할 수 있습니다. 그래서 때로는 앱에 특별한 기능이 있어 필요할 때 데이터 캐시를 비우기도 한다. 그러나 이 데이터 캐시를 지우는 것은 이 시스템의 데이터 캐시를 지우는 것일 뿐, 아니면 이 응용 프로그램의 데이터 캐시만 지우는 것이지 데이터베이스의 데이터 캐시를 지우는 것이 아니다.
둘째, 대부분의 SQL 문은 이 프로세스에 따라 처리됩니다. 우리의 DBA 또는 Oracle 데이터베이스 기반 개발자는 이러한 명령문의 처리 과정을 이해하고 SQL 문을 디버깅하는 데 도움이 됩니다. 때로는 이러한 원칙을 익히면 문제 해결 시간을 줄일 수 있습니다. 특히 데이터베이스는 데이터 조회 권한 심사를 문법과 의미 뒤에 두고 점검한다는 점에 유의해야 한다. 따라서 데이터베이스 권한 제어 원칙만 사용하면 소프트웨어 권한 제어를 적용할 필요가 충족되지 않을 수 있습니다. 이 시점에서 권한 관리 요구 사항을 구현하기 위해 소프트웨어의 포그라운드 설정을 적용해야 합니다. 또한 데이터베이스 권한 관리 응용 프로그램이 다소 번거롭기 때문에 서버에서 처리하는 작업량이 증가할 수 있습니다. 따라서 레코드, 필드 등에 대한 쿼리 권한 제어 , 프로그램에 참여하는 대부분의 사람들은 데이터베이스보다 응용 프로그램에서 구현하는 것을 선호합니다.
Oracle SQL 문 실행 순서
(8) 선택 (9) 거리 (11) < Select _ list & gt
(1) & ltleft _ table & gt 에서
(3) < Join _ type & gt & ltright _ table & gt 추가
(2) on < Join_condition >
(4) 모든 & ltwhere _ condition & gt
(5) 그룹핑 기준 & ltgroup _ by _ list & gt
(6) {CUBE | ROLLUP} 사용
(7) & lthaving _ condition & gt 포함
(10) & ltorder _ by _ list & gt 를 기준으로 주문합니다
1)FROM: FROM 절의 테이블에 대해 데카르트 곱 (상호 연결) 을 수행하여 가상 테이블 VT 1 을 생성합니다.
2)ON: VT 1 에 ON 필터를 적용하고 활성화된 필터만 TV2 에 삽입합니다.
3) outer (조인): OUTER JOIN (CROSS JOIN 또는 INNER JOIN 과 반대) 이 지정된 경우 예약된 테이블의 일치하지 않는 행이 VT2 에 외부 행으로 추가되어 TV3 이 생성됩니다. FROM 절에 두 개 이상의 테이블이 포함된 경우 모든 테이블 위치가 처리될 때까지 마지막 연결에서 생성된 결과 테이블 및 다음 테이블에 대해 1 3 단계를 반복합니다.
4)WHERE: WHERE 필터를 TV3 에 적용합니다. true 로 설정된 행만 TV4 에 삽입됩니다.
5)GROUP BY: GROUP BY 절의 열 목록에 따라 TV4 의 행을 그룹화하여 TV5 를 생성합니다.
6) Cut | Rollup: VT5 에 뛰어난 것을 삽입하여 VT6 을 생성합니다.
7)HAVING: VT6 에 HAVING 필터를 적용합니다. true 인 그룹만 VT7 에 삽입됩니다.
8) 선택: 선택 목록을 처리하여 VT8 을 생성합니다.
9)DISTINCT: VT8, 제품 VT9 에서 중복된 행을 제거합니다.
10)ORDER BY:VT9 의 행은 ORDER BY 절의 열 목록 순서대로 커서 (VC 10) 를 생성하고 TV1/테이블을 생성합니다
위의 각 단계는 다음 단계의 입력으로 사용될 가상 테이블을 생성합니다. 호출자 (클라이언트 응용 프로그램 또는 외부 쿼리) 는 이러한 가상 테이블을 사용할 수 없습니다. 마지막 단계에서 생성된 테이블만 호출자에게 제공됩니다. 질의에 절이 지정되지 않은 경우 해당 단계를 건너뜁니다.