database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Q&A 41328 게시물 읽기
No. 41328
두개의 테이블중 하나의 테이블만 선택해서 효율적으로 조회하는 방법
작성자
곰두리아빠
작성일
2017-02-06 10:53ⓒ
2017-02-06 16:23ⓜ
조회수
6,266

안녕하세요. 

매출_BAK을 우선으로 둘 중 하나의 테이블에서만 데이터를 가져오고 싶습니다. 

근데 이런 쿼리가 성능에 문제가 없는지 고민됩니다. 

10만건 정도의 데이터 입니다. 

 

 

select * from 매출 a

where year =2016

and not exists (select 1 from 매출_BAK B WHERE a.year =b.year)

union all

select * from 매출_BAK

where year = 2016

 더 좋은 방법 없을까요?

 

이 글에 대한 댓글이 총 7건 있습니다.

1. 서브쿼리의 조건을 a.year 가 아닌 상수값 2016 으로 주세요.
  - 상수값 조건시 한번만 수행되는데.
  - a.year 로 조건 주면 상관관계 서브쿼리가 되어 매 행마다 실행됩니다.
2. 연도 항목의 데이터 타입이 숫자형이 맞는지? 확인해보세요.
  - 문자형인데 숫자 조건 주면 인덱스 못탑니다.
3. 우선 순위에 따라 Union All 의 순서를 바꾸는 게 좋을 듯 하구요.
 

마농(manon94)님이 2017-02-06 11:29에 작성한 댓글입니다.

비슷한 쿼리로 테스트했는데 옵티마이저가 왜 HASH가 유리하다고 계속 판단하는지 의아했는데 그래서 그런 거군요~ 따로 서브쿼리를 빼고 상수 조건을 줬더니 빠르게 나온 것도 그래서 그랬던 거군요. 아핫~

조건 값이 2016 하나라서 실행계획도 옵티마이저가 알아서 동일하게 풀지 않을까 했는데 아니네요. 앞으로 어떤 게 더 유리할지 잘 생각해서 조인으로 운용할지 필터로 처리할지 생각하고 짜야겠네요. 감사합니당~

손재균(iikii)님이 2017-02-06 11:56에 작성한 댓글입니다.
이 댓글은 2017-02-06 12:36에 마지막으로 수정되었습니다.

 답변 감사드립니다. 

근데 조건을 상수로 넣으면 not exists 가 아닌 <> 나 not in을 사용해야 할까요? 이렇게 하니 plan에서  인덱스를 안탈것 같아서요.

그러고 보니 애초에 not exists도 인덱스를 안탈것 같네요.

 

곰두리아빠님이 2017-02-06 14:54에 작성한 댓글입니다. Edit

1. 조건을 상수로 바꾸는 것과 NOT EXISTS 는 상관 없습니다.
  - 존재여부를 판단하는 것이므로
  - NOT EXISTS 가 가장 적절해 보입니다.
  - 바꿀 이유가 없구요.
2. 인덱스를 타는 것과 NOT EXISTS 는 상관 없습니다.
  - 인덱스는 연도 조건으로 타는 것이지.
  - NOT EXISTS 로 타는게 아닙니다.
3. 연도컬럼의 다음 두가지를 확인해 보세요.
  - 각 테이블에 인덱스가 있는지?
  - 숫자 타입이 맞는지?

마농(manon94)님이 2017-02-06 15:05에 작성한 댓글입니다.

마농님. 감사드립니다. 

근데 제가 오해하게 글을 쓴거 같네요. 죄송합니다. 

두개의 테이블중 특정 데이터 기준으로 한 태이블에서만 가져오는것이 아니라 둘 중 하나의 테이블에서만 모든 데이터를 가져오려고 합니다. 

매출_BAK 에 2016 데이터가 한건이라도 있다면 매출 테이블은 결과에서 완전히 제외되게 하려고 합니다. 

그렇다면 아래와 같이 하면 될까요?

 

SELECT * FROM 매출_BAK

WHERE YEAR = 2016

UNION ALL

SELECT * FROM 매출

WHERE YEAR =2016

AND YEAR > NVL((SELECT YEAR FROM 매출_BAK WHERE YEAR=2016 AND ROWNUM=1),0)

 

YEAR는 NUMBER 입니다. 

 

 

곰두리아빠님이 2017-02-06 15:49에 작성한 댓글입니다. Edit

EXISTS 서브쿼리의 의미와 동작원리를 잘못 이해하고 계신 듯 하네요.
NOT EXISTS 가 딱 원하시는 바로 그 기능입니다.
위와 같이 복잡하게 작성하셔도 큰 무리는 없겠으나...
바로 딱 그 기능인 EXISTS 가 아닌 다른 방법을 굳이 쓰려고 하시는지?

마농(manon94)님이 2017-02-06 15:59에 작성한 댓글입니다.
이 댓글은 2017-02-06 16:05에 마지막으로 수정되었습니다.

마농님이 정확하게 짚어 주셨네요. 제가 exists의 원리를 조인을 이용한 필터링으로만 이해하고 있었습니다. 말씀하신대로 exists를 다시 보니 참거짓의 의미를 알았네요.

도움 주심 정말 감사드립니다. 

 

곰두리아빠님이 2017-02-06 16:22에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
41332오라클9i -> 오라클10i로 이전 [1]
매수신호
2017-02-13
5783
41331오라클 데이터파일 관련 질문입니다 [2]
이민호
2017-02-10
5748
41330Oracle error SQL문 도와주세요..
도와주세요.
2017-02-07
5679
41328두개의 테이블중 하나의 테이블만 선택해서 효율적으로 조회하는 방법 [7]
곰두리아빠
2017-02-06
6266
41327범위 포함 데이터 제외 쿼리 문의 [1]
김정묵
2017-02-06
5791
41325날짜 term 구하는 sql 문의 [1]
도와주세요.
2017-01-31
6318
41323등록되어 있는 쿠폰테이블에서 쿠폰을 채번하는 경우 [2]
김인수
2017-01-25
5844
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.050초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다