2013-05-13 5 views
0

두 개의 결과 집합에서 Union All을 수행하고 각 결과 집합이 마스터 테이블의 필터링 된 하위 집합과 동일한 내부 조인에서 파생되는 경우 쿼리 엔진이 "적중 "주인 표는 한두 번?DB2 용 SQL 최적화

예 : 나는 모든 문이의 작은 부분 집합 일하게 될 것 UNION 있도록 마스터 테이블의 필터링 된 결과를 저장할 임시 테이블을 만들 도움이 될 것입니다 있는지 확인하기 위해 노력하고

SELECT m.col4, st1.col2 
FROM master m 
    INNER JOIN subTable1 st1 
    on st1.col1 = m.col1 
    WHERE m.col1 = 'a' and m.col2 = 123 and m.col3 = "a1b2" 
UNION ALL 
SELECT m.col4, st2.col2 
FROM master m 
    INNER JOIN subTable2 st2 
    on st2.col1 = m.col1 
    WHERE m.col1 = 'a' and m.col2 = 123 and m.col3 = "a1b2" 

마스터 레코드는 마스터 테이블의 필터링을 두 번 수행하는 대신에 일 수 있습니다. 위의 예제에서 일 수 있습니다.

미리 조언 해 주셔서 감사합니다.

+0

어떤 DB2를 사용하고 있습니까? DB2 for i, DB2 LUW 또는 z/OS 용 DB2? – WarrenT

답변

1

어쩌면 공통 테이블 식 도움이 다음 CTE는 ("수백만"에서 "수천"에서 말) 크게 행의 수를 줄이는 경우

with small_master as (
    select m.col4, 
      m.col1 
    from master 
    where m.col1 = 'a' 
    and m.col2 = 123 
    and m.col3 = 'a1b2' 
) 
SELECT m.col4, st1.col2 
FROM small_master m 
    INNER JOIN subTable1 st1 
    on st1.col1 = m.col1 
UNION ALL 
SELECT m.col4, st2.col2 
FROM small_master m 
    INNER JOIN subTable2 st2 
    on st2.col1 = m.col1; 

내 경험에 (안하지만 DB2와 함께)이 도움이 .

CTE의 중간 결과가 (여전히) 매우 큰 경우 (수 백만)이 경우 도움이되지 않습니다.

그러나 실행 계획 만이 이에 대해 밝힐 수 있습니다.

+0

감사합니다! 나는 이것을 지금 시험해보고 그것을 어떻게 진행하는지 보게 될 것이다. 내가 다시 올릴거야. 다시 한 번 감사드립니다. – rogdawg

+1

이것은 * DB2에 대한 좋은 접근 방법입니다. 감소 된 행의 백분율로 나타낸 전환점은 관련된 테이블의 크기 및 사용 가능한 메모리 양과 같은 시스템 속성 등으로 달라질 수 있습니다. 그러나 WHERE 절이 매우 선택적 인 것처럼 보이므로 여기서 컨테스트가 없어야합니다. 또한 master에는 col1, col2, col3으로 인덱스가 있고 small_master에는 col1로 인덱스가 있다고 가정합니다. 임시 테이블은 사태를 악화시킬뿐입니다. – WarrenT

0

이것은 데이터베이스와 관련된 테이블의 통계에 많이 달려 있습니다. 나는 DB2에 친숙하지 않다.

그러나 성능이 문제인 경우 master(col, col2, col3)에 색인을 추가하는 것이 좋습니다. 이렇게하면 쿼리의 두 부분이 빠르게 처리됩니다.

CTE를 임시 테이블로 사용하는 것은 데이터베이스와 관련이 있습니다. Postgres는 항상 CTE를 인스턴스화하므로 코드는 한 번만 실행됩니다. SQL Server는 결코 작동하지 않습니다. 필자는 이와 관련하여 DB2의 동작을 알지 못합니다. 그러나 쿼리를 수행하는 대신 명시 적으로 성능을 향상시키기 위해 인덱스를 추가하는 것이 좋습니다. 새 쿼리로 인해 테이블 ​​통계가 변경되거나 새 소프트웨어가 릴리스되거나 하드웨어가 업그레이드 될 때 예기치 않은 쿼리 계획이 발생할 수 있습니다.

SQL Server 동작에 대한 참조는 this one 또는 this one 또는 this discussion입니다.

+0

"Postgres는 항상 CTE를 임시 테이블로 변환합니다 *."그거 확실하니? 나는 작은 것들을 생각하면서 기억 속에 남을 것이라고 생각했습니다. –

+0

@a_horse_with_no_name. . . 나는 내가 의미하는 바를 분명히했다. 임시 테이블과 코드를 한 번만 실행하면됩니다. 데이터가 필연적으로 디스크에 닿는다는 의미는 아닙니다. –

+1

설명해 주셔서 감사합니다 (지금은 SQL Server에 대한 진술을 의심합니다) ...) –

1

이런 종류의 "what if"질문에 대답하는 가장 쉬운 방법은 쿼리 계획을 보는 것입니다. 명령어로 쉽게 생성 할 수 있습니다. db2expln -d <your db> -f <your query file> -z <your query delimiter> -gi

일반적으로 작업을 수행하는 가장 빠른 방법 인 단일 SQL 문으로 작업을 수행 할 수 있으므로 임시 테이블을 만들면 성능에 도움이되지 않을 수 있습니다 .