공부, 기록

[SQL Server] 쿼리 개선 - UNION ALL -> OR 조건으로 수정 본문

공부/DATABASE

[SQL Server] 쿼리 개선 - UNION ALL -> OR 조건으로 수정

무는빼주세요 2024. 1. 30. 23:32

DETAIL 테이블의 ParentDetailNo 컬럼으로 조건 조회를 하면서 테이블 풀스캔이 발생함.

해당 테이블에 인덱스 추가 또는 조건절 변경이 필요.

ParentDetailNo  컬럼은 해당 SP에서만 조회 조건으로 사용이 됨(인덱스 설정시 사용하는 쿼리가 하나..)

DETAIL 테이블과 MASTER 테이블 은  1:N 관계이고 MASTER 테이블의 PK 는 ParentDetailNo   컬럼 1:N 관계

MASTER 테이블 DETAIL 테이블 존재 관계는 1: N 또 DETAIL 테이블 내에서 하나의 PK는 여러 다른 ROW의 부모 값이 될 수 있는 상황
위 상황에서 DETAIL 테이블에 새로운 조건으로 WHERE 절이 추가되었고 해당 컬럼은 인덱스가 없는 상태에서 UNION ALL로 처리가 되고 있었음.
구성
테이블 :  MASTER, DETAIL-> 1:N 관계
MASTER PK = MasterNo
DETAIL PK = DetailNo.  DetailNo는 N개의 다른 행의 ParentDetailNo 가 될 수 있다.입력값은 @pi_intDetailNo 만 인입 되는 상황
 
기존 쿼리
SELECT  *
FROM    MASTER AS M WITH(NOLOCK)
JOIN    DETAIL AS D WITH(NOLOCK) ON M.MasterNo = D.MasterNo
WHERE   D.DetailNo = @pi_intDetailNo 
UNION ALL
SELECT  *
FROM    MASTER  AS M WITH(NOLOCK)
JOIN    DETAIL  AS D WITH(NOLOCK) ON M.MasterNo = D.MasterNo 
WHERE   D. ParentDetailNo  = @ pi_intDetailNo 
 
-> 드라이빙 테이블인 MASTER 테이블을 WHERE 조건에서  MasterNo 조회 범위를 줄여주면 인덱스를 사용할것이고 드라이븐 테이블인 DETAIL 테이블은 JOIN 조건에서 사용되는 MasterNo 컬럼의 인덱스를 사용할 것이므로 WHERE 조건에서 DETAIL 테이블은 필터 조건으로만 사용이 될 것으로 생각하였다.
 
개선 쿼리
SELECT @v_MasterNo  = MasterNo 
FROM DETAIL WITH(NOLOCK)
WHERE DetailNo   = @pi_intDetailNo 
 
SELECT *
FROM MASTER  AS M WITH(NOLOCK)
JOIN    DETAIL   AS D WITH(NOLOCK) ON M.MasterNo = D.MasterNo
WHERE M. MasterNo = @v_MasterNo  
AND (D. DetailNo  = @pi_intDetailNo  OR D.ParentDetailNo = @pi_intDetailNo)

 

결국 대부분의 경우 드라이빙 테이블과 드라이븐 테이블에 대해 생각하는게 중요하며 인덱스는 테이블당 대부분의 경우 하나만 사용이 되므로 UNION ALL 없이 OR 조건으로 별도 인덱스 생성 없이 처리가 가능했다.