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 40435 게시물 읽기
No. 40435
다른 디비와 다른오라클에 대한 성향에 대해 문의드립니다.
작성자
김종수(enmu)
작성일
2014-04-17 17:58
조회수
6,724

안녕하세요.

다른 디비를 사용하다 오라클 디비를 접하게 되니 혼란스러움이 극에 달하고 있습니다.

우선, limit/top의 기능이 없어 rownum 을 가지고 한다는 부분에 크게 경악을 하게 되었네요..

아래 두개의 쿼리의 결과가 다르게 나오는데요..

1. select a,b,c from table where rownum <= 4 order by a desc

2. select * from (select a,b,c from table order by a desc) abctable where rownum <= 4

제가 알고있는 내용은 select * from ( SELECT 결과 ) A 로 서브쿼리 형식으로 진행을 하게 되면 메모리 사용이 증가하여

결과적으로 퍼포먼스에 영향을 미치는 것으로 알고 있습니다.  (SELECT 결과) 의 량이 많을 수록, 빈번할수록 부하가 엄청 커지는 것으로 알고있어

위와 같은 구조가 좋지 못한 구조로 알고 있는데, 오라클에서는 달리 방법이 없는 것으로 나타나고 있어 다른 방법이 있는지 문의 드립니다.

 

구하고자 하는 결과는 2번에 대한 결과입니다.

정렬을 진행한 후 해당 결과를 원하는 수량으로 짜르기 위한 방법인데요..

일반적으로 이런경우 어떻게 진행을 하시나요??

아.. 추가적으로 제가 알고있는 서브쿼리 형식으로 진행하는 것이 부하에 미치는게 맞는지,, 오라클은 예외인가요??

 

답변 부탁드립니다.

 

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

쿼리를 바라보는 관점이 잘못되었습니다.
지금 성능을 논하고 있는데요.
성능을 논하기 전에 정확한 결과를 리턴하는지가 우선입니다.
서브쿼리가 없는 1번 쿼리는
성능은 당연히 좋습니다. 그러나 결과가 틀립니다.
틀린 결과에 성능만 좋으면 될까요? 그건 아니죠.
원하는 결과를 얻으려면 2번 쿼리처럼 작성해야 하구요.
오라클만의 얘기가 아닙니다.
작성 방식만 다를 뿐이지 타 DBMS 에서의 동작원리는 동일합니다.
이런 방식의 쿼리를 통틀어 TOP N 쿼리라고 칭합니다.
TOP N 쿼리는 정렬된 결과중 일부분만 원하는 거죠.
인덱스가 있어서 이를 이용할 수 있다면
아예 정렬을 안해도 되고, 일부만 읽고 멈추므로 성능이 가장 좋겠구요.
인덱스가 없어, 풀스캔 및 전체 정렬을 피할 수는 없는 상황에서느
정렬을 위해 필요한 임시공간을 줄여주는것이 관건입니다.
이것을 해주는 것이 바로 TOP N 쿼리입니다.

추가로 오라클 12c 버전부터는 FETCH FIRST 기능이 추가되었습니다.

마농(manon94)님이 2014-04-17 18:20에 작성한 댓글입니다.
이 댓글은 2014-04-18 10:29에 마지막으로 수정되었습니다.

답변 감사합니다.^^

혹시 여기에 댓글을 달아도 확인 후 답변을 달아주실지 모르겠지만,

우선 댓글로 다시한번 질문을 드려봅니다.

말씀하신대로 1번 쿼리와  2번 쿼리의 결과가 다르게 나오는게 맞습니다.

성능보다는 원하는 결과를 구해야 하는 것도 맞습니다.

 

다만, 다른 디비에서는 아래와 같이 쿼리를 작성하였고, 서브쿼리에 대한 디비에 부하를 염려하여 이 부분에 대해 문의를 드립니다. 오라클이라는 브랜드라면 기능이 더 많을 것이라 판단하였고 조금 더 심플하게 작성할 수 있을 것 같다는 생각이 들었습니다.

select top 10 * from abc order by a desc

select * from abc order by a desc limit 10

오라클 12C에서 추가된 FETCH FIRST기능에 대해서는 조금더 확인을 해보도록 하겠습니다.

물론, 오라클의 버전을 올릴 수 없어 적용은 힘들겠지만 말씀해 주셨으니 앞으로를 위해 공부해 두는게 맞을것이라 생각됩니다.

한가지는 아래 1번과 2번의 차이처럼 select  * from () 으로 겉을 더 싸는 것에 대한 부하에 대해 답을 찾고 있습니다.

1. select * from (select * from abc) a

2. select * from (select * from (select * from abc) a) b

 

마농(manon94)님께서 제 궁금한 부분을 채워주셔서 진심으로 감사의 마음을 느낍니다.^^

다시한번 감사드립니다.

 

김종수(enmu)님이 2014-04-18 09:50에 작성한 댓글입니다.

보통 아래처럼 사용합니다.

 

SELECT * FROM (
        SELECT A, B, C
                ,ROW_NUMBER() OVER(ORDER BY T1.A DESC) AS RN 
        FROM TAB T1
)
WHERE RN >= 10 AND RN <= 20 ;

SELECT * FROM (
        SELECT A, B, C, ROWNUM RN 
        FROM TAB T1
        ORDER BY A DESC
)
WHERE RN >= 10 AND RN <= 20 ;

박성빈(빈이님)님이 2014-04-18 10:18에 작성한 댓글입니다.

위 댓글에서 이미 언급한 내용인데요.

빨간색으로 처리했구요.

부연설명 드리겠습니다.

DBMS 마다 작성방식은 다르지만 동작방식은 동일합니다.(아마도)

즉 겉만 보시면 안됩니다.

서브쿼리를 사용했는지 안했는지가 중요한게 아닙니다.

실제로 어떻게 동작하느냐가 중요합니다.

SQL 만 보지 마시고 실행계획을 확인해 보세요.

마농(manon94)님이 2014-04-18 10:31에 작성한 댓글입니다.
이 댓글은 2014-04-18 10:33에 마지막으로 수정되었습니다.

박성빈님도 잘못 사용하셨네요.

Row_Number 사용법은 맞지만

Rownum 사용법은 틀렸습니다.

Rownum 을 정렬과 함께 사용하면 안되죠.

이러면 Rownum 이 정렬보다 우선 적용됩니다.

정렬 결과에 대해 나중에 Rownum 을 사용해야 합니다.

마농(manon94)님이 2014-04-18 10:35에 작성한 댓글입니다.
이 댓글은 2014-04-18 10:37에 마지막으로 수정되었습니다.

박성빈님, 마농님 제 질문에 관심을 가져 주셔서 다시한번 감사드립니다.

등록해 주신 답변의 내용을 각인하면서 제가 저를 이해시키는데 필요한 자료들을 더 찾아보아야 할 것 같습니다.^^

덕분에 자료를 찾는데 좋은 방안들을 알수 있었습니다.

감사합니다.

김종수(enmu)님이 2014-04-18 11:27에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
40438염치없지만..마농(manon94)님... [2]
한상원
2014-04-21
6884
40437예약 서비스 서버 구성
서버구성
2014-04-21
6303
40436첫번째 row를 select하고 싶은데.. [2]
한상원
2014-04-18
6461
40435다른 디비와 다른오라클에 대한 성향에 대해 문의드립니다. [6]
김종수
2014-04-17
6724
40434role과 privs 기초 질문!
임서희
2014-04-17
6802
404332개의 서버에 1개의 db일경우 select update 질문
김주환
2014-04-17
6033
40432[ORA-01438]초보자입니다. 도와주세요. [2]
이용훈
2014-04-16
6073
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.021초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다