1번 방법은 인덱스만 풀스캔 후 그룹바이 하고 결과건수만큼만 인덱스 스캔하여 테이블 읽습니다.
==> 그닥 나쁜 방법이 아닙니다.
2번 방법은 쿼리가 좀 틀렸네요. 그룹바이가 없어야 에러 안나겠지요.
==> 성능은 유사합니다. 어차피 인덱스 풀스캔후 rn=1로 걸러낸 자료만큼 인덱스 타지요.
1번보다 2번이 나을것은 없어 보입니다. 유사하게 동작합니다.
가장 확실한 성능개선 방법은 인덱스의 순서가 바뀌어야 합니다.(지역, 일자)
지역테이블을 따로 두고 지역테이블을 읽으면서 그 건수만큼 인덱스 Desc 스캔하면서 rownum= 1 하는 것입니다.
이렇게 되면 인덱스 풀스캔을 안해도 되지요.
-- 조건이 없기 때문에 전체 테이블을 읽을수밖에 없습니다. -- 조건이 없는 한 전체데이터를 읽는 것은 어쩔수 없습니다. -- 이 때 위 두가지 쿼리는 테이블 대신 인덱스를 전체 읽습니다. -- 전체 데이터를 읽은 후 Max만 추려내는 과정에서 비용을 줄여야 하는데요. -- 위 두가지 방법 모두 효율적인 방법입니다. -- 그룹바이나 정열을 위한 버퍼가 전체 데티터 만큼 잡히는게 아니라 -- 필요한 결과수 만큼만 잡히는 거죠. -- 테이블풀스캔보다는 인덱스 풀스캔이 그나마 비용이 적겠지요. 테이블 컬럼들이 아주 많다면요. -- 테이블 크기보다 인덱스 크기가 작으니까요. -- 그러나 컬럼들이 몇개 안된다면 차라리 테이블 풀스캔이 나을 수도 있습니다. -- 인덱스풀스캔은 싱글블럭I/O 이지만 테이블풀스캔은 멀티블럭I/O 이지요. -- 멀티블럭 I/O 로 인덱스를 읽게 하려면 INDEX_FFS 힌트를 사용하셔야 하구요. -- 인덱스 페스트 풀스캔도 시도해 보시구요. -- 다음과 같이 인덱스를 경유하지 않고 차라리 테이블 풀스캔하는 방법도 시도해 보세요. SELECT * FROM (SELECT 매출.* , RANK() OVER(PARTITION BY 지역 ORDER BY 마감일 DESC) rk FROM 매출 ) WHERE rk = 1 ; -- 그리고 뷰인 경우 뷰를 조회할때 혹시 지역조건을 주는 경우가 있지 않나요? -- 만약 뷰 조회시 지역조건을 주고 조회한다면? -- rank 보다는 Group By 가 나을 수도 있습니다. -- 조건이 뷰 안으로 침투할 수 있기 때문이죠.