본문 바로가기

연구개발/DBA

Join을 걸면 무조건 느려진다는 오해(100714)

728x90
반응형

목적 : OLTP 업무에서 Join을 걸면 느려진다는 오해를 파헤쳐 보자

 

Table 현황(코드 테이블을 참조하는 1 : N 관계)

ERD.PNG 

 

코드 테이블 작성

CREATE TABLE [dbo].[CODE]

(

       [CODE] [varchar](1) NOT NULL,

       [CODENAME] [varchar](10) NULL,

       CONSTRAINT PK_CODE PRIMARY KEY CLUSTERED (CODE)

)

Insert into CODE values ('A','에이')

Insert into CODE values ('B','')

Insert into CODE values ('C','')

GO

 

참조 테이블 작성

CREATE TABLE [dbo].[CODE_RE]

(

       NUM INT NOT NULL,

       [CODE] [varchar](1) NOT NULL,

       dumy [varchar](10) NULL,

       CONSTRAINT PK_COMP_CODE PRIMARY KEY CLUSTERED (NUM)

)

GO

With temp(num)

as

(

       select 1 num 

        union all

       select num+1  from temp

       where num+1 <=10

)

INSERT INTO [CODE_RE]

Select A.num, CASE WHEN  A.num % 3 = 0 THEN 'A'

                   WHEN  A.num % 3 = 1 THEN 'B'

                   WHEN  A.num % 3 = 2 THEN 'C'

              END AS [CODE], Left(newid(),3) dumy

From Temp A

GO

 

관계 설정

ALTER TABLE [dbo].[CODE_RE] with check

ADD CONSTRAINT [FK_GUBUN] FOREIGN KEY([CODE]) REFERENCES [dbo].[CODE] ([CODE])

 

 

 

Table 내용 확인

SELECT * FROM CODE

T.PNG 

 

SELECT * FROM CODE_RE

 T2.PNG

 

 

조인 후 실행계획 확인(하기 두 쿼리의 결과는 같다)

Select B.CODE,NUM,DUMY FROM CODE A

INNER JOIN [CODE_RE] B

On A.CODE = B.CODE

  

Select A.CODE,NUM,DUMY  FROM CODE A

INNER JOIN [CODE_RE] B

On A.CODE = B.CODE

 

결과.PNG 

 

2개의 쿼리를 비교해 보면  한 글자 만 다르고  결과는 같지만 비용은 3배의 차이가 벌어진다.

옵티마이저가 참조한(부모)  테이블은 무결성을 보장한다고 믿고 불필요한 비용을 삭제해 버린다.  (옵티마이저의 Logical TR) 

즉 DB의 무결성을 보장하면서 조인의 영향을 전혀 받지 않는 것이다.

소스 코드를 보면 Exist 를 사용한 코드를 너무 많이 볼 수 있다. 즉 무결성 보장을 위해 소스단에서 더 많은 비용을 들이면서 Join은

무조건 느리다는 편견으로 사용을 하지 않는 것이다.

 

물론 조인 후 컬럼명 하나 잘못써서 쓸데 없는 비용이 발생하는 것을 막는 것은 DBA의 몫이다.

문제 생기면 닥치는 대로 인덱스만 거는게 아닌 기초부터 튼튼한 DBA가 되야 겠다.

 

728x90
반응형