오라클은 insert 한 순서대로 select 되지 않는군요? 0 10 11,413

by 박진규 [SQL Query] [2010.11.22 17:47:36]


yjacket20101122.png (68,795Bytes)

mssql table 에 primary key 를 자동증가값으로 해놨을때 
select 는 insert 순서대로 select 되는 것이 보장되던데, 
검색해보니 oralce 에선 order by 나 IOT 를 사용하는 방법이 최선인듯합니다.(맞나요?)

인덱스가 여럿있어야 하는 테이블이라 IOT 는 어려울 것 같고
천상 order by 를 써야 하겠는데 작은? 문제가 있네요..

테이블 만들고, 테스트 데이터 넣었습니다.

create table TestTable (
id number primary key not null,
data nvarchar2(100) null
)
go

INSERT INTO TestTable
SELECT LEVEL cnt, DBMS_RANDOM.value() FROM DUAL CONNECT BY LEVEL < 10000
go

이제 조회를 위한 쿼리입니다.

SELECT * FROM TestTable

이렇게 쿼리 하면 id 순서대로 안나오니까 이렇게 해야겠죠.

SELECT * FROM TestTable ORDER BY id

근데 문제는 order by 로 인한 cpu 비용이 엄청나게 상승하는데 있습니다.(첨부이미지)
성능 손실 없이 삽입 순서를 유지하는 방법이 없을까요?

* 추가 * 
현님 코멘트 대로 힌트를 이용해 PK 인덱스를 태워본 결과스샷을 더합니다.
성능이 많이 좋아졌습니다만 그래도 성능 손실이 제법 있네요. 다른 방법은 없을까요?

by xx [2010.11.22 18:07:11]
id를 pk로 잡으시고 자동증가값(시퀀스)로 잡으시면 됩니다.

by 박진규 [2010.11.22 18:39:47]
xx님 지금 그렇게 한건데요..

by 현 [2010.11.22 19:02:41]
id를 pk로 잡으셨으면 pk로 정렬을 하시면 됩니다.
즉, order by를 사용하지 마시고,
힌트를 사용하여 pk 인덱스 스캔을 하도록 하면 정렬된 조회를 하실 수 있습니다.

by 박진규 [2010.11.22 19:45:27]
현님 조언대로 하니 order by 보다 훨씬 향상된 결과가 나오네요!
하지만 그래도 성능손실이 생기는게 안타깝습니다.
한 2배정도 느린것 같은데, 손실없는 방법은 없을까요?

by 이재현 [2010.11.22 21:54:16]
불필요한 손실 보단..

슬때없는 데아타를 가져오는거 같은데요.. 음.

by 마농 [2010.11.22 22:26:03]
조회시 필요한 컬럼들을 모두 결합인덱스로 설정하시면.
테이블 스캔 없이 인덱스 스캔만으로도 자료 조회가 가능합니다.
그러나 이는 하나의 문제 해결을 위한 단편적인 방법이며 또다른 문제를 야기할 수 있습니다.
하지만 모든 해결방법이 마찬가지로 장점이 잇다면 단점이 있게 마련이구요.
제 생각엔 자료가 몇건 안된다면 정렬해도 크게 느리지 않다는 것입니다.
실제로 성능이 눈에 띄게 저하되서 질문하신것인지?
왜 위와 같은 요구조건이 필요한 것인지?
다른 대안은 없는지 고민해 보셔야 하지 않을까요?

by 현 [2010.11.23 08:47:46]
일반적으로 풀스캔을 하면 인덱스 스캔을 하는 것 보다 안좋다라고 생각하시는 경향이 있습니다.
그러나 데이터 전체를 봐야 한다면 인덱스 스캔보다는 풀스캔이 훨씬 성능면에서 유리 합니다.
인덱스 스캔은 single block random access, 풀스캔은 multi block access 를하기 때문입니다.
인덱스 스캔은 랜덤 엑세스를 하긴 하지만 정렬이 되어 있다는 장점을 가지고 있구요....
또한 데이터의 일부분만 봐야 한다면 인덱스 스캔이 유리하겠죠...

위에 마농님이 말씀하신대로 장단점이 있습니다.
두마리 토끼를 모두 다 잡기는 어렵겠지만,
요구되는 성능 범위안에서 가장 최선이 무엇인지 고민해야 할 필요가 있습니다.

by 박진규 [2010.11.23 11:18:31]
마농님, 현님, 자료가 많은 테이블이 작업대상입니다...ㅠ_ㅠ 순서대로 한 몇십개씩 끊어 읽는데 다음읽기의 기준값을 읽어온 마지막 id 로 삼으려구요. 그래서 id 순서가 보장 되야 되는데, 별도 정렬을 안해도 되는 방법이 있을 줄 알았거든요.

사실 비용에 목숨걸어야 하는 상황은 아니구요
그냥 best practice 가 무엇일지 궁금해서요^^

많은 도움 되었습니다.

by 마농 [2010.11.23 13:07:57]
말씀 하신대로 몇십개씩만 조회하는 것이라면?
id 인덱스를 이용하시면 됩니다.
테이블에 값이 순차적으로 들어있을 필요는 없습니다.
인덱스를 이용해 필요건수만큼만 가져 온후 스캔을 멈추면 되기 때문에
전체 자료를 정렬해야 하는 부담은 없는거구요.

by xx [2010.11.23 14:17:02]
id도 pk로 잡아놓으셨다니 더이상 할일은 없습니다.
where id > start_value and id < end_value
이렇게만 하셔도 됩니다. 이 이상을 원하신다면 다른 방법을 찾아보셔야..
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입