오라클(ORACLE) 강의

Order By

NickTop 2023. 9. 15. 21:27

정렬

Order by로 정렬 수행

select cust_id,cust_last_name, cust_credit_limit
from custs
order by cust_id;

---------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |      1 |        |   622 (100)|     50 |00:00:00.04 |    1139 |   1123 |       |       |          |
|   1 |  SORT ORDER BY     |       |      1 |  55500 |   622   (1)|     50 |00:00:00.04 |    1139 |   1123 |  2320K|   704K| 2062K (0)|
|   2 |   TABLE ACCESS FULL| CUSTS |      1 |  55500 |   314   (1)|  55500 |00:00:00.03 |    1139 |   1123 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------------------

만약, cust_id가 constraint로 not null이 없으면 index 되어있더라도 Table Full Scan한다,

또는, 디스크 IO 때문에 not null이 constraint로 있더라도 Table Full Scan 할 수도 있다.

단, FIRST_ROW 모드 방식에서는 인덱스를 통해 정렬 연산없이 첫번째값을 바로 찾을 수 있기 때문에 무조건 index를 활용한다

alter session set optimizer_mode = first_rows;

select cust_id,cust_last_name, cust_credit_limit
from custs
order by cust_id;

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |      1 |        | 54002 (100)|     50 |00:00:00.01 |      52 |      5 |
|   1 |  TABLE ACCESS BY INDEX ROWID| CUSTS     |      1 |  55500 | 54002   (1)|     50 |00:00:00.01 |      52 |      5 |
|   2 |   INDEX FULL SCAN           | CUST_IX01 |      1 |  55500 |   116   (0)|     50 |00:00:00.01 |       2 |      5 |
-------------------------------------------------------------------------------------------------------------------------

 

Stop key

top K 만 알고 싶을 때 rownum을 stop key로 써서 전체 sort를 수행하지 않아도 된다

select *
from (
 select cust_city, cust_credit_limit, cust_last_name, cust_first_name
 from custs
 order by cust_credit_limit desc)
where rownum<=10;

-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name  | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |      1 |        |   758 (100)|     10 |00:00:00.01 |    1139 |       |       |          |
|*  1 |  COUNT STOPKEY          |       |      1 |        |            |     10 |00:00:00.01 |    1139 |       |       |          |
|   2 |   VIEW                  |       |      1 |  55500 |   758   (1)|     10 |00:00:00.01 |    1139 |       |       |          |
|*  3 |    SORT ORDER BY STOPKEY|       |      1 |  55500 |   758   (1)|     10 |00:00:00.01 |    1139 |  2048 |  2048 | 2048  (0)|
|   4 |     TABLE ACCESS FULL   | CUSTS |      1 |  55500 |   314   (1)|  55500 |00:00:00.01 |    1139 |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------

하지만 마찬가지로 Table Full Scan을 하면 55500건의 행을 scan 했으므로 인덱스를 활용하지 못하는 경우에는 도움이 안된다

 

select *
from (
 select cust_city, cust_credit_limit, cust_last_name, cust_first_name
 from custs
 where cust_credit_limit is not null
 order by cust_credit_limit desc)
where rownum<=10;

------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name            | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                 |      1 |        |     4 (100)|     10 |00:00:00.01 |       5 |
|*  1 |  COUNT STOPKEY                |                 |      1 |        |            |     10 |00:00:00.01 |       5 |
|   2 |   VIEW                        |                 |      1 |     10 |     4   (0)|     10 |00:00:00.01 |       5 |
|   3 |    TABLE ACCESS BY INDEX ROWID| CUSTS           |      1 |  55500 |     4   (0)|     10 |00:00:00.01 |       5 |
|*  4 |     INDEX FULL SCAN DESCENDING| CUSTS_LIMIT_IDX |      1 |     10 |     2   (0)|     10 |00:00:00.01 |       2 |
------------------------------------------------------------------------------------------------------------------------

위와 같이 인덱스를 활용하면 10개의 row만 scan하면 된다

 

파티션 (참고)

더보기

장점

- 병렬처리

  힌트 :  SELECT /*+ FULL( S ) PARALLEL(4) */ COUNT(*) 

- pruning : 불필요한 디스크 access 안해도 됨

- paritition wise join : 해당 파티션끼리만 조인 가능

 

종류

- Range partioning : 값의 범위에 따라

- Hash partitioning : 해시 함수 사용, 데이터가 고르게 분포됨, 따라서 병렬 퍼포먼스 향상

- List partitioning : 사용자가 값 지정 (i.e. 지역명을 파티션키로 정함)

- Composite partitioning : 위 3개를 섞음

 

 

강의정보

https://www.multicampus.com/search?siteAppntSrcwdNm=&siteRalSrcwdNm=&kwd=%EC%97%85%EB%AC%B4%EC%97%90+%EB%B0%94%EB%A1%9C+%EC%93%B0%EB%8A%94+SQL+%ED%8A%9C%EB%8B%9D&input_kwd=%EC%97%85%EB%AC%B4%EC%97%90+%EB%B0%94%EB%A1%9C+%EC%93%B0%EB%8A%94+SQL+%ED%8A%9C%EB%8B%9D&category=TOTAL 

 

멀티캠퍼스

삼성계열 기업교육 전문기업, HRD컨설팅, 러닝플랫폼, 법정의무, IT업스킬링, 외국어, MBA, 메타버스러닝

www.multicampus.com

 

'오라클(ORACLE) 강의' 카테고리의 다른 글

그룹 및 집계 함수  (0) 2023.09.15
JOIN / 서브쿼리  (0) 2023.09.14
인덱스  (0) 2023.09.12
Optimizer / 실행 계획  (0) 2023.09.12