๊ธฐ๋ณธ ๋ฉ”์ปค๋‹ˆ์ฆ˜

img
begin 
    for outer in (select ์‚ฌ์›๋ฒˆํ˜ธ, ์‚ฌ์›๋ช… from ์‚ฌ์› where ์ž…์‚ฌ์ผ์ž >= '19960101')
    loop -- outer ๋ฃจํ”„
        for inner in (select ๊ณ ๊ฐ๋ช…, ์ „ํ™”๋ฒˆํ˜ธ from ๊ณ ๊ฐ where ๊ด€๋ฆฌ์‚ฌ์›๋ฒˆํ˜ธ = outer.์‚ฌ์›๋ฒˆํ˜ธ)
        loop -- inner ๋ฃจํ”„
            dbms_output.put_line(outer.์‚ฌ์›๋ช… || ' : ' || inner.๊ณ ๊ฐ๋ช… || ' : ' || inner.์ „ํ™”๋ฒˆํ˜ธ);
        end loop; 
    end loop; 
end; 
img
Inner์—์„œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

NL ์กฐ์ธ ์‹คํ–‰๊ณ„ํš ์ œ์–ด

Execution Plan
-----------------------------------------------------------------------
0      SELECT STATEMENT Optimizer=ALL_ROWS
1  0    NESTED LOOPS
2  1      TABLE ACCESS (BY INDEX ROWID) OF '์‚ฌ์›' (TABLE)
3  2        INDEX (RANGE SCAN) OF '์‚ฌ์›_X1' (INDEX)
4  1      TABLE ACCESS (BY INDEX ROWID) OF '๊ณ ๊ฐ' (TABLE)
5  4        INDEX (RANGE SCAN) OF '๊ณ ๊ฐ_X1' (INDEX)
-- ์‚ฌ์› ํ…Œ์ด๋ธ”(Driving ๋˜๋Š” Outer Table) ๊ธฐ์ค€์œผ๋กœ ๊ณ ๊ฐ ํ…Œ์ด๋ธ”(Inner Table)๊ณผ NL ์กฐ์ธํ•˜๋ผ
SELECT /*+ ORDERED USE_NL(C) */ *
FROM ์‚ฌ์› E, ๊ณ ๊ฐ C
WHERE E.์ž…์‚ฌ์ผ์ž >= '19960101'
AND C.๊ด€๋ฆฌ์‚ฌ์›๋ฒˆํ˜ธ = E.์‚ฌ์›๋ฒˆํ˜ธ

-- 3๊ฐœ ์ด์ƒ
-- A > B > C > D ์ˆœ์œผ๋กœ ์กฐ์ธํ•˜๋ผ
-- B์™€ ์กฐ์ธํ•  ๋•Œ, ๊ทธ๋ฆฌ๊ณ  C์™€ ์ด์–ด์„œ ์กฐ์ธํ•  ๋•Œ๋Š” NL, D์™€ ์กฐ์ธํ•  ๋•Œ๋Š” ํ•ด์‹œ ์กฐ์ธํ•˜๋ผ
SELECT /*+ ORDERED USE_NL(B) USE_NL(C) USE_HASH(D) */
FROM A, B, C, D
...

-- ordered ๋Œ€์‹  leading ํžŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋จ
-- from์ ˆ์„ ๋ฐ”๊ตฌ์ง€ ์•Š๊ณ ๋„ ์ˆœ์„œ๋ฅผ ์ œ์–ด ๊ฐ€๋Šฅ
SELECT /*+ LEADING(C, A, D, B) USE_NL(A) USE_NL(D) USE_HASH(B) */
FROM A, B, C, D

-- ordered๋‚˜ leadingํžŒํŠธ๊ฐ€ ์—†์œผ๋ฉด, ์ˆœ์„œ๋Š” ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์Šค์Šค๋กœ ํŒ๋‹จ
SELECT /*+ USE_NL(A, B, C, D) */
FROM A, B, C, D
...

NL์กฐ์ธ ์ˆ˜ํ–‰ ๊ณผ์ • ๋ถ„์„

SELECT /*+ ORDERED USE_NL(C) INDEX(E) INDEX(C) */ *
FROM ์‚ฌ์› E, ๊ณ ๊ฐ C
WHERE C.๊ด€๋ฆฌ์ž์‚ฌ์›๋ฒˆํ˜ธ = E.์‚ฌ์›๋ฒˆํ˜ธ
AND E.์ž…์‚ฌ์ผ์ž >= '19960101'
AND E.๋ถ€์„œ์ฝ”๋“œ = 'Z123'
AND C.์ตœ์ข…์ฃผ๋ฌธ๊ธˆ์•ก >= 20000

/* ์ธ๋ฑ์Šค ๊ตฌ์„ฑ */
์‚ฌ์›_PK : ์‚ฌ์›๋ฒˆํ˜ธ, ์‚ฌ์›_X1 : ์ž…์‚ฌ์ผ์ž
๊ณ ๊ฐ_PK : ๊ณ ๊ฐ๋ฒˆํ˜ธ, ๊ณ ๊ฐ_X1 : ๊ด€๋ฆฌ์‚ฌ์›๋ฒˆํ˜ธ, ๊ณ ๊ฐ_X2 : ์ตœ์ข…์ฃผ๋ฌธ๊ธˆ์•ก
----------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT             |        |     5 |    58 |    5 |
|   1 |  NESTED LOOPS                |        |     5 |    58 |    5 |
|   2 |   TABLE ACCESS BY INDEX ROWID| ์‚ฌ์›    |     3 |    20 |    2 |
|   3 |    INDEX RANGE SCAN          | ์‚ฌ์›_X1 |     5 |       |    1 |
|   4 |   TABLE ACCESS BY INDEX ROWID| ๊ณ ๊ฐ    |     5 |    76 |    2 |
|   5 |    INDEX RANGE SCAN          | ๊ณ ๊ฐ_X1 |     8 |       |    1 |
----------------------------------------------------------------------
img
NL ์กฐ์ธ ์ˆ˜ํ–‰ ์ ˆ์ฐจ

NL์กฐ์ธ ํŠœ๋‹ ํฌ์ธํŠธ

์˜ฌ๋ฐ”๋ฅธ ์กฐ์ธ ๋ฉ”์†Œ๋“œ ์„ ํƒ

NL์กฐ์ธ ํŠน์ง• ์š”์•ฝ

-- ๋ถ€๋ถ„๋ฒ”์œ„ ์ฒ˜๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜๋ฉด, ์กฐํšŒ๋ฅผ ํ•˜์ž๋งˆ์ž ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ์ถœ๋ ฅํ•˜๊ธฐ ์‹œ์ž‘
SELECT /*+ ORDERED USE_NL(B) INDEX_DESC(A (๊ฒŒ์‹œํŒ๊ตฌ๋ถ„, ๋“ฑ๋ก์ผ์‹œ)) */
FROM ๊ฒŒ์‹œํŒ A, ์‚ฌ์šฉ์ž B
WHERE A.๊ฒŒ์‹œํŒ๊ตฌ๋ถ„ = 'NEWS' --๊ฒŒ์‹œํŒ IDX : ๊ฒŒ์‹œํŒ ๊ตฌ๋ถ„ + ๋“ฑ๋ก์ผ์‹œ
AND B.์‚ฌ์šฉ์žID = A.์ž‘์„ฑ์žID
ORDER BY A.๋“ฑ๋ก์ผ์‹œ DESC

NL์กฐ์ธ ํŠœ๋‹ ์‹ค์Šต

SELECT /*+ ORDERED USE_NL(C) INDEX(E) INDEX(C) */ *
FROM   ์‚ฌ์› E, ๊ณ ๊ฐ C
WHERE  C.๊ด€๋ฆฌ์‚ฌ์›๋ฒˆํ˜ธ = E.์‚ฌ์›๋ฒˆํ˜ธ
AND    E.์ž…์‚ฌ์ผ์ž    >= '19960101'
AND    E.๋ถ€์„œ์ฝ”๋“œ    = 'Z123'
AND    C.์ตœ์ข…์ฃผ๋ฌธ๊ธˆ์•ก >= 20000
ROWS    ROW SOURCE OPERATION
------- -------------------------------------------------------
      5 NESTED LOOPS
      3   TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์›
   2780     INDEX RANGE SCAN OF ์‚ฌ์›_X1
      5   TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1
ROWS    ROW SOURCE OPERATION
------- -------------------------------------------------------
      5 NESTED LOOPS
      3   TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์›
      3     INDEX RANGE SCAN OF ์‚ฌ์›_X1
      5   TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1
ROWS    ROW SOURCE OPERATION
------- -----------------------------------------------------------------------
      5 NESTED LOOPS (CR=112 PR=34 PW=0 TIME=122 US)
      3   TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์› (CR=105 PR=32 PW=0 TIME=118 US)
      3     INDEX RANGE SCAN OF ์‚ฌ์›_X1 (CR=102 PR=31 PW=0 TIME=16)
      5   TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ (CR=7 PR=2 PW=0 TIME=4 US)
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1 (CR=5 PR=1 PW=0 TIME=0 US)
ROWS    ROW SOURCE OPERATION
------- -----------------------------------------------------------------------
      5 NESTED LOOPS (CR=2732 PR=386 PW=0 TIME=...)
   2780   TABLE ACCESS BY INDEX ROWID ์‚ฌ์› (CR=166 PR=2 PW=0 TIME=...)
   2780     INDEX RANGE SCAN ์‚ฌ์›_X1 (CR=4 PR=0 PW=0 TIME=...)
      5   TABLE ACCESS BY INDEX ROWID ๊ณ ๊ฐ (CR=2566 PR=384 PW=0 TIME=...)
      8     INDEX RANGE SCAN ๊ณ ๊ฐ_X1 (CR=2558 PR=383 PW=0 TIME=...)

NL์กฐ์ธ ํ™•์žฅ ๋งค์ปค๋‹ˆ์ฆ˜

-- ์ „ํ†ต์ ์ธ NL์กฐ์ธ
ROWS    ROW SOURCE OPERATION
------- -------------------------------------------------------
      5 NESTED LOOPS
      3   TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์›
      5     INDEX RANGE SCAN OF ์‚ฌ์›_X1
      5   TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1

-- Prefetch ์‹คํ–‰๊ณ„ํš
-- Inner์ชฝ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋””์Šคํฌ I/O ๊ณผ์ •์—์„œ ํ…Œ์ด๋ธ” Prefetch ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Œ์„ ํ‘œ์‹œ
ROWS    ROW SOURCE OPERATION
------- -------------------------------------------------------
      5 TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ
     12   NESTED LOOPS
      3     TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์›
      3       INDEX RANGE SCAN OF ์‚ฌ์›_X1
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1

-- ๋ฐฐ์น˜ I/O ์‹คํ–‰๊ณ„ํš
-- Inner ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋””์Šคํฌ I/O ๊ณผ์ •์—์„œ ๋ฐฐ์น˜ I/O ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Œ์„ ํ‘œ์‹œ
ROWS    ROW SOURCE OPERATION
------- -------------------------------------------------------
      5 NESTED LOOPS
      8   NESTED LOOPS
      3     TABLE ACCESS BY INDEX ROWID OF ์‚ฌ์›
      3       INDEX RANGE SCAN OF ์‚ฌ์›_X1
      8     INDEX RANGE SCAN OF ๊ณ ๊ฐ_X1
      5   TABLE ACCESS BY INDEX ROWID OF ๊ณ ๊ฐ
SELECT /*+ ORDERED USE_NL(B) */
       A.๋“ฑ๋ก์ผ์‹œ, A.๋ฒˆํ˜ธ, A.์ œ๋ชฉ, B.ํšŒ์›๋ช…, A.๊ฒŒ์‹œํŒ์œ ํ˜•, A.์งˆ๋ฌธ์œ ํ˜•
FROM (
    SELECT A.*, ROWNUM NO
    FROM (
        SELECT ๋“ฑ๋ก์ผ์‹œ, ๋ฒˆํ˜ธ, ์ œ๋ชฉ, ์ž‘์„ฑ์ž๋ฒˆํ˜ธ, ๊ฒŒ์‹œํŒ์œ ํ˜•, ์งˆ๋ฌธ์œ ํ˜•
        FROM   ๊ฒŒ์‹œํŒ
        WHERE  ๊ฒŒ์‹œํŒ์œ ํ˜• = :TYPE
        ORDER BY ๋“ฑ๋ก์ผ์‹œ DESC  -- ์ธ๋ฑ์Šค ๊ตฌ์„ฑ : ๊ฒŒ์‹œํŒ์œ ํ˜• + ๋“ฑ๋ก์ผ์‹œ
    ) A
    WHERE ROWNUM <= (:PAGE * 10)
) A, ํšŒ์› B
WHERE A.NO >= (:PAGE-1)*10 + 1
AND   B.ํšŒ์›๋ฒˆํ˜ธ = A.์ž‘์„ฑ์ž๋ฒˆํ˜ธ
ORDER BY A.๋“ฑ๋ก์ผ์‹œ DESC    -- 11G๋ถ€ํ„ฐ ์—ฌ๊ธฐ์— ORDER BY๋ฅผ ๋ช…์‹œํ•ด์•ผ ์ •๋ ฌ ์ˆœ์„œ ๋ณด์žฅ

์ž๊ฐ€์ง„๋‹จ

-- ์ธ๋ฑ์Šค
PRA_HST_STC_N1 : SALE_ORG_ID + STRD_GRP_ID + STRD_ID + STC_DT

-- ์ฟผ๋ฆฌ
SELECT *
FROM PRA_HST_STC A, ODM_TRMS B
WHERE A.SALE_ORG_ID = :sale_org_id
AND A.STRD_GRP_ID = B.STRD_GRP_ID
AND A.STRD_ID = B.STRD_ID
ORDER BY A.STC_DT DESC

-- ํžŒํŠธ: ์•„๋ž˜์ฒ˜๋Ÿผ inner ํ…Œ์ด๋ธ” alias๋ฅผ ์™ผ์ชฝ์— ๊ธฐ์ˆ ํ•˜๋Š” ๊ฒƒ์ด ์ž์—ฐ์Šค๋Ÿฌ์›€
SELECT *
FROM PRA_HST_STC A, ODM_TRMS B
WHERE A.SALE_ORG_ID = :sale_org_id
AND B.STRD_GRP_ID = A.STRD_GRP_ID
AND B.STRD_ID = A.STRD_ID
ORDER BY A.STC_DT DESC