Maystyle :
Admin : New post
Guestbook
Local
media
Catergories
Recent Articles
Recent Comments
Recent Trackbacks
Calendar
Tag
Archive
Link
Search
 
  Logical Query Processing 01 
작성일시 : 2009. 2. 5. 17:37 | 분류 : SQL Server/Kernel

출처 : Inside Microsoft SQL Server 2005 : T-SQL Querying

굉장히 훌륭한 책임에도 번역서가 없기에 보기 힘든 책이 INSIDE SQL SERVER 시리즈다.
물론 완역은 시간 상 힘들겠지만, 각 내용의 요점 정도로 축약하여 기록하고자 한다.

본인은 SQL Server 초보이기 때문에 내용의 이해에 다소간의 문제가 있을 것으로 예상한다.
즉 완벽한 이해와 오역의 방지를 위하여 책과 함께 봐야 도움이 되리라 생각한다.

SQL Server에서는 쿼리를 어떻게 처리할까?
아래와 같은 Table Customers 와 Orders 을 만들고 간단한 Select query 구문을 처리하는 과정을 통해 SQL Server의 Logical Query Processing을 알아보도록 하자.

Query 구문

select c.customerid, COUNT(o.orderid) as numorders
from customers as c
    left outer join orders as o
        on c.customerid = o.customerid
where c.city='madrid'
group by c.customerid
having COUNT(o.orderid) <3
order by numorders

샘플 데이터 구성 (DDL)
use tempdb
go

create table customers
(
    customerid    char(5)        not null primary key,
    city        varchar(10)    not null
);

insert into customers values ('FISSA', 'Madrid');
insert into customers values ('FRNDO', 'Madrid');
insert into customers values ('KRLOS', 'Madrid');
insert into customers values ('MRPHS', 'Zion');

create table orders
(
    orderid        int        not null    primary key,
    customerid    char(5)    null        references customers(customerid)
);

insert into orders values (1, 'FRNDO');
insert into orders values (2, 'FRNDO');
insert into orders values (3, 'KRLOS');
insert into orders values (4, 'KRLOS');
insert into orders values (5, 'KRLOS');
insert into orders values (6, 'MRPHS');
insert into orders values (7, null);

Step 1 Cartesian Product (Cross Join)
가장 먼저 From 조건을 확인하여 가상의 Table을 만든다. 처음으로 만들어지는 테이블은 customers 와 orders로 조합이 가능한 모든 가능의 수를 조합하여 테이블이 만들게 된다. 즉 M개의 행을 가진 T1 와 N개의 행을 가진 T2가 Join 이 되면 M x N 행을 가진 가상의 테이블이 만들어지게 된다.

VT1
FISSA    Madrid    1    FRNDO
FISSA    Madrid    2    FRNDO
FISSA    Madrid    3    KRLOS
FISSA    Madrid    4    KRLOS
FISSA    Madrid    5    KRLOS
FISSA    Madrid    6    MRPHS
FISSA    Madrid    7    NULL
FRNDO    Madrid    1    FRNDO
FRNDO    Madrid    2    FRNDO
FRNDO    Madrid    3    KRLOS
FRNDO    Madrid    4    KRLOS
FRNDO    Madrid    5    KRLOS
FRNDO    Madrid    6    MRPHS
FRNDO    Madrid    7    NULL
KRLOS    Madrid    1    FRNDO
KRLOS    Madrid    2    FRNDO
KRLOS    Madrid    3    KRLOS
KRLOS    Madrid    4    KRLOS
KRLOS    Madrid    5    KRLOS
KRLOS    Madrid    6    MRPHS
KRLOS    Madrid    7    NULL
MRPHS    zion    1    FRNDO
MRPHS    zion    2    FRNDO
MRPHS    zion    3    KRLOS
MRPHS    zion    4    KRLOS
MRPHS    zion    5    KRLOS
MRPHS    zion    6    MRPHS
MRPHS    zion    7    NULL

Step 2 Applying the ON Filter (Join Condition)
VT1 테이블에서 on c.customerid = o.customerid 확인하여 True 인 절로 VT2 를 생성 한다.

VT2
FRNDO    Madrid    1    FRNDO
FRNDO    Madrid    2    FRNDO
KRLOS    Madrid    3    KRLOS
KRLOS    Madrid    4    KRLOS
KRLOS    Madrid    5    KRLOS
MRPHS    zion    6    MRPHS

Step3 Adding Outer Rows
On Condition에서 제외된 Row 들일지라도 필요할 경우 Outer Join을 통해 가상 테이블에 포함 시킬 수 있다.
즉 이전에 생성된 VT2에 제외된  outer row를 추가하게 된다.

VT3
FISSA    Madrid    NULL    NULL
FRNDO    Madrid    1    FRNDO
FRNDO    Madrid    2    FRNDO
KRLOS    Madrid    3    KRLOS
KRLOS    Madrid    4    KRLOS
KRLOS    Madrid    5    KRLOS
MRPHS    zion    6    MRPHS

Step4 Applying the where filter
Where condition을 확인하여 해당 결과가 True 인 Row들로 이루어진 새로운 테이블을 만든다.
Where 구문과 On 구문의 차이점은 Outer 조인일 때 필터링 이후에 Row가 추가되는냐 않되느냐 이다.
물론 inner 조인의 경우 위의 Step3의 단계를 거치지 않기 때문에 구문이 무의미 한다. 하지만 Outer Join 인 경우 위에서 보는 것처럼 On 조건은 Step3 이전에 Where 조건은 Step3 이후에 적용 되게 된다.

VT4
FISSA    Madrid    NULL    NULL
FRNDO    Madrid    1    FRNDO
FRNDO    Madrid    2    FRNDO
KRLOS    Madrid    3    KRLOS
KRLOS    Madrid    4    KRLOS
KRLOS    Madrid    5    KRLOS

Step5 Grouping
group by c.customerid 조건에 맞춰 그룹핑을 한다. 이때 Select 절에는 Count (Orderid)와 같은 형식의 각 그룹당 하나의 결과만 리턴 하도록 해야 한다.
그리고 만약 Group by all 을 이용할 경우에는 Step4의 Where가 무시되게 된다.
마지막으로 Count() 함수는 NULL도 하나의 값으로 처리하게 되지만 SUM, AVG, MIN, MAX는 해당 연살 칼럼에 NULL이 있을 경우 NULL로 처리하게 된다.

VT5
FISSA    Madrid    NULL    NULL
FRNDO    Madrid    1    FRNDO
            Madrid    2    FRNDO
KRLOS    Madrid    3    KRLOS
            Madrid    4    KRLOS
            Madrid    5    KRLOS

|