with문, inlineview 질문있습니다. 1 4 693

by 아싸헛스윙 [SQL Query] [2018.10.17 15:48:41]


안녕하세요.  선배님들 

평소에 쿼리를 인라인뷰를 많이 작성하는데요. 

 

1. 인라인뷰

left outer join (
    셀렉트 구문~~~ 주렁주렁
) 별칭 on 조인조건

 

2. cte 사용 시 

with 별칭1 (필요한 테이블 셀렉트~~)

, 별칭2(필요한 테이블 셀렉트2~~)

 

select 컬럼 from 별칭1 

조인 별칭2~~~~~

 

원래 1번처럼 괄호안에 다시 셀렉트하여 사용하는데

이러한게 2~3개 필요하면 쿼리가 엄청 길어지더라구요 제가 짠건데도 나중에 보면 좀 보기 힘들기도하고..

책을 보니 인라인뷰를 cte문으로 빼서 쓰면 좋다고 해서 바꿔봤는데..

이렇게 하니 상단에 미리 짜놓으니 아래 셀렉트 구문에서 핵심만 파악하고 위에서 변수선언처럼 쿼리내용을 보니 

좋은거같기도하고 아닌거같기도하고...

어느게 더 속도적으로 효율적인지, 유지보수하기 가독성이 좋은지.. 고민이 되서요

실행계획은 볼줄모르고... 대충 속도는 좀 비슷한거같긴한데 결과도 같구요

어느게 더 나은 방향인지 판단이 안되는데 도움좀 부탁드립니다.

감사합니다. 좋은하루되세요!

 

 

 

by 우리집아찌 [2018.10.17 16:31:29]
-- 어느것을 써도 실행계획은 같습니다.

-- WITH 절이용
WITH V_DEPT AS (
 SELECT * FROM DEPT WHERE LOC = 'DALLAS'
)

SELECT  /*+ gather_plan_statistics */
       A.* 
  FROM EMP A
     , V_DEPT B
 WHERE A.DEPTNO = B.DEPTNO ;
 
 
 
----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      5 |00:00:00.01 |      12 |       |       |          |
|*  1 |  HASH JOIN         |      |      1 |      5 |      5 |00:00:00.01 |      12 |  1517K|  1517K|  405K (0)|
|*  2 |   TABLE ACCESS FULL| DEPT |      1 |      1 |      1 |00:00:00.01 |       6 |       |       |          |
|   3 |   TABLE ACCESS FULL| EMP  |      1 |     14 |     14 |00:00:00.01 |       6 |       |       |          |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("A"."DEPTNO"="DEPT"."DEPTNO")
   2 - filter("LOC"='DALLAS')
 
 
 
---------------------------------------------------------------------------------------------------------------

-- INLINE VIEW 이용

SELECT  /*+ gather_plan_statistics */
       A.* 
  FROM EMP A
     , ( SELECT * FROM DEPT WHERE LOC = 'DALLAS')  B
 WHERE A.DEPTNO = B.DEPTNO ;
 
 
----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      5 |00:00:00.01 |      12 |       |       |          |
|*  1 |  HASH JOIN         |      |      1 |      5 |      5 |00:00:00.01 |      12 |  1517K|  1517K|  646K (0)|
|*  2 |   TABLE ACCESS FULL| DEPT |      1 |      1 |      1 |00:00:00.01 |       6 |       |       |          |
|   3 |   TABLE ACCESS FULL| EMP  |      1 |     14 |     14 |00:00:00.01 |       6 |       |       |          |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("A"."DEPTNO"="DEPT"."DEPTNO")
   2 - filter("LOC"='DALLAS')

 


by 아싸헛스윙 [2018.10.17 17:46:05]

아 실행계획도 같군요.. 답변감사합니다!!


by 마농 [2018.10.17 16:38:11]

WITH 문은 두 가지 동작방식이 있습니다.
 - 인라인뷰처럼 동작하기도 하고.
 - 임시테이블처럼 동작하기도 합니다.
인라인뷰처럼 동작한다면? 성능상 차이가 없겠죠.
어떤 방식으로 동작되는지는 실행계획을 확인해 보세요.
다른 방식으론 임시테이블스페이스에 임시테이블을 생성하고 사용하게 됩니다.
조회하는데 테이블을 디스크에 내려쓰고 사용하니 비효율이죠.
초창기 with 는 무조건 disk 로 내려 썼는데
지금은 일부 메모리에서도 처리되는 걸로 비효율을 줄인 걸로 압니다.
그래서 with 문의 집합이
  - 한번만 사용되는 쿼리라면? 인라인뷰로 동작하구요.
  - 여러번 사용되는 쿼리라면? 임시테이블 생성합니다.
with 구문이 복잡하고 느린 쿼리인데 여러번 사용된다면?
  - 인라인뷰로 동작하게 되면 느린 쿼리가 여러번 수행되겠지요.
  - 임시테이블 생성하면 느린 쿼리 한번만 수행해서 재사용하게 됩니다.
"이게 좋다더라"라는 말만 듣고 선택하면 안됩니다.
이는 "이런 경우에는 이게 좋다더라" 에서 앞에 단서조항이 빠진 말입니다.
경우에 따라 이게 유리할 수 도 있고 저게 유리할 수도 있습니다.
가독성을 높이는 방법으로 WITH 가 사용될 수 도 있지만
지나치게 with 만 사용하면 오히려 가독성이 떨어질 수 도 있습니다.

가독성을 높이려면
  - 삐뚤빼뚤 -> 들여쓰기, 줄맞춤
  - 이어쓰기 -> 내려쓰기
  - 대문자만/소문자만/아무렇게나 -> 대소문자 구분(명령어는 대문자, 명칭은 소문자)
  - 컴마의 위치(저는 앞쪽 컴마를 선호합니다. 사람마다 선호도 차이 있음)
등등의 방법이 있습니다.
하지만 가장 좋은 방법은 쿼리 자체를 간결하게 바꾸는 것입니다.
쿼리가 복잡하고 길면 가독성이 떨어집니다.


by 아싸헛스윙 [2018.10.17 17:46:59]

지적해 주신부분 너무 감사드려요..

너무 흑백논리로 바라본거같네요

with절에 대해 자세히 설명해주셔서 감사합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입