명백한 성능상의 이유로 "not in"절과 관련된 상호 관련된 하위 쿼리를 포함하는 기존 Oracle SQL 쿼리를 다시 작성하고 싶습니다. 이것은 외부 조인 또는 다른 기술을 통해 수행 할 수 있습니까?
다음은 코드입니다.
SELECT TRIM(et.event_id), TRIM(et.cancel_evt_id)
FROM external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
WHERE et.acct = 'ABCDEF'
AND tt.transaction_type_class != 'XYZXYZ'
AND
(
TRIM(et.event_id) NOT IN
(
SELECT TRIM(t1.transaction_evt_id)
FROM transactions t1
WHERE t1.acct = et.acct
AND t1.asset_id = et.asset_id
AND t1.cancel_flag = 'N'
)
OR TRIM(et.cancel_evt_id) NOT IN
(
SELECT TRIM(t2.cancel_evt_id)
FROM transactions t2
WHERE t2.acct = et.acct
AND t2.asset_id = et.asset_id
AND t2.cancel_flag = 'Y'
)
)
;
주석을 제외하고 이것은 "ID"열이 문자열이 아닌 정수 기반이라고 가정하고 변환하지 마십시오.
또한 쿼리를 최적화하는 데 도움이되도록 색인이 있는지 확인하겠습니다.
External_Transactions ( acct, event_id, cancel_evt_id )
Transaction_Type ( transaction_type_id, transaction_type_class )
Transactions ( transaction_evt_id, acct, asset_id, cancel_flag )
Transactions ( cancel_evt_id, acct, asset_id, cancel_flag )
SELECT
et.event_id,
et.cancel_evt_id
FROM
external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
AND tt.transaction_type_class != 'XYZXYZ'
LEFT OUTER JOIN transactions t1
ON et.event_id = t1.transaction_evt_id
AND et.acct = t1.acct
AND et.asset_id = t1.asset_id
AND t1.cancel_flag = 'N'
LEFT OUTER JOIN transactions t2
ON et.cancel_evt_id = t2.cancel_evt_id
AND et.acct = t2.acct
AND et.asset_id = t2.asset_id
AND t2.cancel_flag = 'Y'
WHERE
et.acct = 'ABCDEF'
AND ( t1.transaction_evt_id IS NULL
OR t2.cancel_evt_id IS NULL )
트랜잭션 테이블에 인덱스가 있으면 약간의 이점을 얻을 수 있습니다.
Transactions ( acct, asset_id, cancel_flag, transaction_evt_id, cancel_evt_id )
왼쪽 조인은
SELECT
et.event_id,
et.cancel_evt_id
FROM
external_transactions et
JOIN transaction_type tt
ON et.transaction_type_id = tt.transaction_type_id
AND tt.transaction_type_class != 'XYZXYZ'
LEFT OUTER JOIN transactions t1
ON et.acct = t1.acct
AND et.asset_id = t1.asset_id
AND (
( t1.cancel_flag = 'N'
AND et.event_id = t1.transaction_evt_id )
OR
( t1.cancel_flag = 'Y'
AND et.cancel_event_id = t1.cancel_evt_id )
)
WHERE
et.acct = 'ABCDEF'
AND t1.transaction_evt_id IS NULL
두 경우 모두 인덱스는 COVERING 인덱스이므로 레코드의 다른 요소를 확인하기 위해 원시 데이터 페이지로 돌아갈 필요가 없습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다