2014-07-16 2 views
1

내가 테이블 ACCPLAN이 조인 (PRIMARY KEY : ACCOUNT_ID)오라클 SQL : 연합과는

ACCOUNT_ID     PLAN_TYPE   OTHER_STUFF 

ACC1      PLAN_TYPE_ONE  .... 
ACC2      PLAN_TYPE_TWO  .... 
ACC3      PLAN_TYPE_ONE  .... 
ACC4      PLAN_TYPE_TWO  ... 

I가 하나 이상의 테이블 ACCTRANSACTION (PRIMARY KEY -> (ACCOUNT_ID, TRANSACTION_ID)

ACCOUNT_ID TRANSACTION_ID TRANSACTION_AMOUNT TXN_TYPE 

ACC1  1    100    TXN_TYPE_1 
ACC1  2    300    TXN_TYPE_2 
ACC2  1    400    TXN_TYPE_2 
ACC3  1    400    TXN_TYPE_3 

고정 plan_types 5 개와 고정 txn_types20 개가 있습니다. 각각의 plan_type에 대해 가능한 거래 유형 만 있습니다 (예 : 의 경우 TXN_TYPE_1 및 TXN_TYPE_2, PLAN_TYPE_TWO의 경우 TXT_TYPE_2 및 TXN_TYPE_2는 가능)

나는이 2 가지 방법

1

각 plan_type에 대한 검색 접근 방식으로 수행 할 수 있습니다

ACCPLAN

에서 거래 ACCTRANSACTION 정보 및 기타
세부 정보를 검색하고, 노동 조합을하려고

select ap.account_id,ap.other_stuff,at.transaction_amount 
from accplan ap, acctransaction at 
where ap.account_id = at.account_id 
and ap.plan_type = PLAN_TYPE_ONE 
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2); 

union 

select ap.account_id,ap.other_stuff,at.transaction_amount 
from accplan ap, acctransaction at 
where ap.account_id = at.account_id 
and ap.plan_type = PLAN_TYPE_TWO 
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3); 

union 

... 

접근법 2

,536,913 63,210

더 나은 두 테이블이 큰 데이터를 고려하고 접근 모든 plan_types

select ap.account_id,ap.other_stuff,at.transaction_amount 
    from accplan ap, acctransaction at 
    where ap.account_id = at.account_id 
    and 
    ((ap.plan_type = PLAN_TYPE_ONE and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2)) 

    or 

    (ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3)); 

에 대해 하나의 쿼리를 사용하여 검색? 제발 제안 해주세요.

+0

의견은 논점에 근거하고 있기 때문에 폐회 투표를하겠습니다. 여기에있는 이쪽은 오프 주제입니다. 두 쿼리 모두에서 Explain Plain을 실행하여 어느 것이 데이터베이스에 가장 적합한 지 확인해야합니다. –

+0

본인은이 문맥에서 "최고"라는 말은 가장 빠른 것임을 이해합니다. 이것은 알고있는 데이터베이스 (오라클)에서 측정하고 재현 할 수 있습니다. 데이터베이스의 실행 계획을 이해하면 많은 결과 (색인, 통계, 버전, 구성 옵션, 하드웨어)에 영향을 미칠 수 있지만 무엇이 더 빠를 수 있는지에 대한 좋은 아이디어를 줄 수 있습니다. 어쨌든 일부 스택 교환 사이트로 리디렉션 될 수있는 많은 성능 관련 질문이 주기적으로 발생합니다. 이것에 대해 메타에서 어떤 것이 있습니까? – borjab

+0

당신의 질문과는 무관합니다 : 당신은'where' 절에서 오래된 구식 암시 적 조인을 사용하지 말고'from' 절의 명시 적'JOIN' 연산자를 사용해야합니다. 나는 또한 두 번째 것이 아마도 더 효율적이라고 동의한다. 그럼에도 불구하고 첫 번째 것을 원한다면 중복을 제거하는 오버 헤드를 피하기 위해'UNION ALL'을 사용해야합니다. –

답변

2

조인을 사용하십시오. 유니온은 전체 결과를 정렬해야하며 데이터베이스에 많은 비용이 듭니다.

또한. 한 번 테이블을 읽은 다음 더 작은 수표를 만들기 위해 여러 번 읽는 것보다 각 레코드마다 복잡한 검사를하는 것이 좋습니다.

면책 조항 : 데이터베이스 쿼리 계획자가 큰 조건이 충분히 선택 적이 지 않은 것으로 판단하고 인덱스를 사용하지 않고 작은 쿼리를 사용하는 경우 첫 번째 쿼리가 더 빠르게 실행되는 매우 이상한 구석을 상상할 수 있습니다. 행 수가 많을수록 두 번째 옵션을 더 많이 사용하게됩니다.

+0

+1 좋은 설명과 면책 조항. 오라클에는 UNION과 관련된 몇 가지 변형이 있지만 여기에는 적용되지 않는다는 점은 주목할 가치가 있습니다. 예를 들어 [USE_CONCAT] (http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements006.htm # BABIAFIB) 힌트는'OR'을'UNION ALL'으로 변환하고, [join factorization] (https://blogs.oracle.com/optimizer/entry/optimizer_transformations_join_factorization)은'UNION ALL'에서 큰 테이블을 다시 읽을 수 없게합니다. 이상하게도 join 인수 분해는 * more * 복잡한 시나리오와 만 작동하며 이러한 간단한 쿼리에 도움이되지 않습니다. –

+0

글쎄,'UNION' 대신에'UNION ALL'을 사용할 때 정렬을 피할 수 있습니다. –

+1

UNION ALL이 빠릅니다. 그는 중복을 염두에 두지 않거나 그럴 수있는 중복이 없다고 확신하는 경우 사용할 수 있습니다. UNION ALL을 사용한다고해도 JOIN 연산자는 명시 적으로 JOIN 연산자를 사용합니다. – borjab