Oracle/Tuning2020. 9. 16. 16:41

์ฟผ๋ฆฌ ๋ณ€ํ™˜์„ ํ†ตํ•ด Top-N ์ฟผ๋ฆฌ์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•œ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด์ž.


์•„๋ž˜์™€ ๊ฐ™์ด ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์ž.
-- 1
DROP TABLE t1 PURGE;
DROP TABLE t2 PURGE;

CREATE TABLE t1 AS SELECT ROWNUM AS c1, ROWNUM AS c2 FROM XMLTABLE ('1 to 100000');
CREATE TABLE t2 AS SELECT * FROM t1;

ALTER TABLE t2 ADD CONSTRAINT t2_pk PRIMARY KEY (c1);

์•„๋ž˜๋Š” t1, t2 ํ…Œ์ด๋ธ”์„ ์•„์šฐํ„ฐ ์กฐ์ธํ•œ Top-N ์ฟผ๋ฆฌ๋‹ค. t1, t2 ํ…Œ์ด๋ธ”์ด ํ•ด์‹œ ์กฐ์ธ๋˜์–ด 418๊ฐœ์˜ ๋ธ”๋ก I/O๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
-- 2
SELECT *
  FROM (SELECT   *
            FROM t1 a
            LEFT OUTER
            JOIN t2 b
              ON b.c1 = a.c2
           WHERE a.c1 > 0
        ORDER BY a.c1) a
 WHERE ROWNUM <= 10;

--------------------------------------------------------------------
| Id  | Operation               | Name | Starts | A-Rows | Buffers |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |      1 |     10 |     418 |
|*  1 |  COUNT STOPKEY          |      |      1 |     10 |     418 |
|   2 |   VIEW                  |      |      1 |     10 |     418 |
|*  3 |    SORT ORDER BY STOPKEY|      |      1 |     10 |     418 |
|*  4 |     HASH JOIN OUTER     |      |      1 |    100K|     418 |
|*  5 |      TABLE ACCESS FULL  | T1   |      1 |    100K|     209 |
|   6 |      TABLE ACCESS FULL  | T2   |      1 |    100K|     209 |
--------------------------------------------------------------------

2๋ฒˆ ์ฟผ๋ฆฌ๋Š” ์•„์šฐํ„ฐ ์กฐ์ธํ•œ t2 ํ…Œ์ด๋ธ”์˜ c1 ์นผ๋Ÿผ์ด PK์ด๋ฏ€๋กœ ์•„๋ž˜ ์ฟผ๋ฆฌ์ฒ˜๋Ÿผ Top-N ์ฒ˜๋ฆฌ ํ›„ t2 ํ…Œ์ด๋ธ”์„ ์กฐ์ธํ•ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๋™์ผํ•˜๋‹ค. t2 ํ…Œ์ด๋ธ”์˜ NL ์กฐ์ธ๋˜์–ด ๋ธ”๋ก I/O๊ฐ€ 229๊ฐœ๋กœ ๊ฐ์†Œํ–ˆ๋‹ค.
-- 3
SELECT *
  FROM (SELECT   *
            FROM t1 a
           WHERE a.c1 > 0
        ORDER BY a.c1) a
  LEFT OUTER
  JOIN t2 b
    ON b.c1 = a.c2
 WHERE ROWNUM <= 10;

---------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | A-Rows | Buffers |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |     10 |     229 |
|*  1 |  COUNT STOPKEY                |       |      1 |     10 |     229 |
|   2 |   NESTED LOOPS OUTER          |       |      1 |     10 |     229 |
|   3 |    VIEW                       |       |      1 |     10 |     209 |
|   4 |     SORT ORDER BY             |       |      1 |     10 |     209 |
|*  5 |      TABLE ACCESS FULL        | T1    |      1 |    100K|     209 |
|   6 |    TABLE ACCESS BY INDEX ROWID| T2    |     10 |     10 |      20 |
|*  7 |     INDEX UNIQUE SCAN         | T2_PK |     10 |     10 |      10 |
---------------------------------------------------------------------------

์•„๋ž˜์™€ ๊ฐ™์ด t2 ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋™์  ์กฐ๊ฑด์ด ์กด์žฌํ•œ๋‹ค๋ฉด ์ฟผ๋ฆฌ๋ฅผ 3๋ฒˆ ์ฟผ๋ฆฌ์ฒ˜๋Ÿผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. ๋™์  ์กฐ๊ฑด๊ณผ ํ•จ๊ป˜ ์•„์šฐํ„ฐ ์กฐ์ธ๊นŒ์ง€ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ์„ฑ๋Šฅ ์ธก๋ฉด์—์„œ ๊ฐ€์žฅ ํšจ์œจ์ ์ด์ง€๋งŒ ๊ฐœ๋ฐœ ๋‚œ์ด๋„๊ฐ€ ๋†’์•„์ง€๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

-- 4
SELECT *
  FROM (SELECT   *
            FROM t1 a
            LEFT OUTER
            JOIN t2 b
              ON b.c1 = a.c2
           WHERE a.c1 > 0
             AND b.c2 > 0 -- ๋™์  ์กฐ๊ฑด
        ORDER BY a.c1) a
 WHERE ROWNUM <= 10;

--------------------------------------------------------------------
| Id  | Operation               | Name | Starts | A-Rows | Buffers |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |      1 |     10 |     418 |
|*  1 |  COUNT STOPKEY          |      |      1 |     10 |     418 |
|   2 |   VIEW                  |      |      1 |     10 |     418 |
|*  3 |    SORT ORDER BY STOPKEY|      |      1 |     10 |     418 |
|*  4 |     HASH JOIN           |      |      1 |    100K|     418 |
|*  5 |      TABLE ACCESS FULL  | T1   |      1 |    100K|     209 |
|*  6 |      TABLE ACCESS FULL  | T2   |      1 |    100K|     209 |
--------------------------------------------------------------------

์•„๋ž˜์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•ด๋ณด์ž. ์ธ๋ผ์ธ ๋ทฐ์˜ SELECT ๋ชฉ๋ก์„ t1 ํ…Œ์ด๋ธ”๋งŒ ์กฐํšŒํ–ˆ๊ณ , Top-N ์ฒ˜๋ฆฌ ํ›„์— t2 ํ…Œ์ด๋ธ”์„ ์•„์šฐํ„ฐ ์กฐ์ธํ–ˆ๋‹ค. ์ค‘๋ณต ์กฐ์ธ์œผ๋กœ ์ธํ•ด ๋ธ”๋ก I/O๊ฐ€ 5๋ฒˆ ์ฟผ๋ฆฌ๋ณด๋‹ค 20๊ฐœ ์ฆ๊ฐ€ํ–ˆ๋‹ค. ์ „์ฒด ๋ธ”๋ก I/O์— ๋น„ํ•ด ํฌ์ง€ ์•Š์€ ์ˆ˜์น˜๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
-- 5
SELECT *
  FROM (SELECT   a.*      -- ๋ณ€๊ฒฝ
            FROM t1 a
            LEFT OUTER
            JOIN t2 b
              ON b.c1 = a.c2
           WHERE a.c1 > 0
             AND b.c2 > 0 -- ๋™์  ์กฐ๊ฑด
        ORDER BY a.c1) a
  LEFT OUTER
  JOIN t2 b
    ON b.c1 = a.c2
 WHERE ROWNUM <= 10;

---------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | A-Rows | Buffers |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |     10 |     438 |
|*  1 |  COUNT STOPKEY                |       |      1 |     10 |     438 |
|   2 |   NESTED LOOPS OUTER          |       |      1 |     10 |     438 |
|   3 |    VIEW                       |       |      1 |     10 |     418 |
|   4 |     SORT ORDER BY             |       |      1 |     10 |     418 |
|*  5 |      HASH JOIN                |       |      1 |    100K|     418 |
|*  6 |       TABLE ACCESS FULL       | T1    |      1 |    100K|     209 |
|*  7 |       TABLE ACCESS FULL       | T2    |      1 |    100K|     209 |
|   8 |    TABLE ACCESS BY INDEX ROWID| T2    |     10 |     10 |      20 |
|*  9 |     INDEX UNIQUE SCAN         | T2_PK |     10 |     10 |      10 |
---------------------------------------------------------------------------

์•„๋ž˜ ์ฟผ๋ฆฌ๋Š” ๋™์  ์กฐ๊ฑด์ด ๋น„ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ •ํ•˜์—ฌ ๋™์  ์กฐ๊ฑด์„ ์ฃผ์„ ์ฒ˜๋ฆฌํ–ˆ๋‹ค. ์ฟผ๋ฆฌ ๋ณ€ํ™˜์— ์˜ํ•ด ์ธ๋ผ์ธ ๋ทฐ ๋‚ด์—์„œ t2 ํ…Œ์ด๋ธ”์˜ ์กฐ์ธ์ด ์ œ๊ฑฐ๋˜์—ˆ๋‹ค. ๋ธ”๋ก I/O๊ฐ€ 3๋ฒˆ ์ฟผ๋ฆฌ์™€ ๋™์ผํ•˜๊ฒŒ 229๊ฐœ๋งŒ ๋ฐœ์ƒํ•œ๋‹ค. ์ฟผ๋ฆฌ ๋ณ€ํ™˜์„ ํ†ตํ•ด ๋™์  ์กฐ๊ฑด์ด ๋น„ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ๋ธ”๋ก I/O๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๋Š” ๊ฐœ์„  ๋ฐฉ์•ˆ์ด๋‹ค.

-- 6
SELECT *
  FROM (SELECT   a.*      -- ๋ณ€๊ฒฝ
            FROM t1 a
            LEFT OUTER
            JOIN t2 b
              ON b.c1 = a.c2
           WHERE a.c1 > 0
          -- AND b.c2 > 0 -- ๋™์  ์กฐ๊ฑด
        ORDER BY a.c1) a
  LEFT OUTER
  JOIN t2 b
    ON b.c1 = a.c2
 WHERE ROWNUM <= 10;

---------------------------------------------------------------------------
| Id  | Operation                     | Name  | Starts | A-Rows | Buffers |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |       |      1 |     10 |     229 |
|*  1 |  COUNT STOPKEY                |       |      1 |     10 |     229 |
|   2 |   NESTED LOOPS OUTER          |       |      1 |     10 |     229 |
|   3 |    VIEW                       |       |      1 |     10 |     209 |
|   4 |     SORT ORDER BY             |       |      1 |     10 |     209 |
|*  5 |      TABLE ACCESS FULL        | T1    |      1 |    100K|     209 |
|   6 |    TABLE ACCESS BY INDEX ROWID| T2    |     10 |     10 |      20 |
|*  7 |     INDEX UNIQUE SCAN         | T2_PK |     10 |     10 |      10 |
---------------------------------------------------------------------------

์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋„ ๋™์ผํ•œ ๊ธฐ๋ฒ•์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ์ฟผ๋ฆฌ๋Š” ๋™์  ์กฐ๊ฑด์— ์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. 101,000๊ฐœ์˜ ๋ธ”๋ก I/O๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
-- 7
SELECT a.*
  FROM (SELECT   a.*
               , (SELECT MAX (x.c2) FROM t2 x WHERE x.c1 = a.c2) AS xc2
            FROM t1 a
        ORDER BY a.c1) a
 WHERE ROWNUM <= 10
   AND a.xc2 > 0 -- ๋™์  ์กฐ๊ฑด
;

--------------------------------------------------------------------------
| Id  | Operation                    | Name  | Starts | A-Rows | Buffers |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |      1 |     10 |     101K|
|   1 |  SORT AGGREGATE              |       |    100K|    100K|     101K|
|   2 |   TABLE ACCESS BY INDEX ROWID| T2    |    100K|    100K|     101K|
|*  3 |    INDEX UNIQUE SCAN         | T2_PK |    100K|    100K|    1462 |
|*  4 |  COUNT STOPKEY               |       |      1 |     10 |     101K|
|*  5 |   VIEW                       |       |      1 |     10 |     101K|
|   6 |    SORT ORDER BY             |       |      1 |     10 |     101K|
|   7 |     TABLE ACCESS FULL        | T1    |      1 |    100K|     209 |
--------------------------------------------------------------------------

์•„๋ž˜์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•ด๋ณด์ž. ๋ฉ”์ธ ์ฟผ๋ฆฌ์˜ SELECT ๋ชฉ๋ก์—์„œ t1 ํ…Œ์ด๋ธ”๋งŒ ์กฐํšŒํ–ˆ๊ณ , ์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋ฅผ ์ค‘๋ณต ๊ธฐ์ˆ ํ–ˆ๋‹ค. ์ค‘๋ณต ์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋กœ ์ธํ•ด ๋ธ”๋ก I/O๊ฐ€ 7๋ฒˆ ์ฟผ๋ฆฌ๋ณด๋‹ค 20๊ฐœ ์ฆ๊ฐ€ํ–ˆ๋‹ค.

-- 8
SELECT a.c1 -- ๋ณ€๊ฒฝ
     , a.c2 -- ๋ณ€๊ฒฝ
     , (SELECT MAX (x.c2) FROM t2 x WHERE x.c1 = a.c2) AS xc2
  FROM (SELECT   a.*
               , (SELECT MAX (x.c2) FROM t2 x WHERE x.c1 = a.c2) AS xc2
            FROM t1 a
        ORDER BY a.c1) a
 WHERE ROWNUM <= 10
   AND a.xc2 > 0 -- ๋™์  ์กฐ๊ฑด
;

----------------------------------------------------------------------------
| Id  | Operation                      | Name  | Starts | A-Rows | Buffers |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |       |      1 |     10 |     101K|
|   1 |  SORT AGGREGATE                |       |     10 |     10 |      20 |
|   2 |   TABLE ACCESS BY INDEX ROWID  | T2    |     10 |     10 |      20 |
|*  3 |    INDEX UNIQUE SCAN           | T2_PK |     10 |     10 |      10 |
|*  4 |  COUNT STOPKEY                 |       |      1 |     10 |     101K|
|*  5 |   VIEW                         |       |      1 |     10 |     101K|
|   6 |    SORT AGGREGATE              |       |    100K|    100K|     101K|
|   7 |     TABLE ACCESS BY INDEX ROWID| T2    |    100K|    100K|     101K|
|*  8 |      INDEX UNIQUE SCAN         | T2_PK |    100K|    100K|    1462 |
|   9 |    SORT ORDER BY               |       |      1 |     10 |     101K|
|  10 |     TABLE ACCESS FULL          | T1    |      1 |    100K|     209 |
----------------------------------------------------------------------------

์•„๋ž˜ ์ฟผ๋ฆฌ๋Š” ๋™์  ์กฐ๊ฑด์„ ์ฃผ์„ ์ฒ˜๋ฆฌํ–ˆ๋‹ค. ์•„์šฐํ„ฐ ์กฐ์ธ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ฟผ๋ฆฌ ๋ณ€ํ™˜์— ์˜ํ•ด ์Šค์นผ๋ผ ์„œ๋ธŒ ์ฟผ๋ฆฌ๊ฐ€ ์ œ๊ฑฐ๋˜์–ด ๋ธ”๋ก I/O๊ฐ€ 209๊ฐœ๋งŒ ๋ฐœ์ƒํ•œ๋‹ค.

-- 9
SELECT a.c1 -- ๋ณ€๊ฒฝ
     , a.c2 -- ๋ณ€๊ฒฝ
     , (SELECT MAX (x.c2) FROM t2 x WHERE x.c1 = a.c2) AS c2x
  FROM (SELECT   a.*
               , (SELECT MAX (x.c2) FROM t2 x WHERE x.c1 = a.c2) AS xc2
            FROM t1 a
        ORDER BY a.c1) a
 WHERE ROWNUM <= 10
-- AND a.xc2 > 0 -- ๋™์  ์กฐ๊ฑด
;

--------------------------------------------------------------------------
| Id  | Operation                    | Name  | Starts | A-Rows | Buffers |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |      1 |     10 |     209 |
|   1 |  SORT AGGREGATE              |       |     10 |     10 |      20 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T2    |     10 |     10 |      20 |
|*  3 |    INDEX UNIQUE SCAN         | T2_PK |     10 |     10 |      10 |
|*  4 |  COUNT STOPKEY               |       |      1 |     10 |     209 |
|   5 |   VIEW                       |       |      1 |     10 |     209 |
|*  6 |    SORT ORDER BY STOPKEY     |       |      1 |     10 |     209 |
|   7 |     TABLE ACCESS FULL        | T1    |      1 |    100K|     209 |
--------------------------------------------------------------------------


Posted by ์ •ํฌ๋ฝ_