【sql調優】cardinality測試與簡析

yellowlee發表於2010-09-10

版本10249208

昨天一個puber的公司生產資料庫有點問題,在執行一個過程的時候IO上到100%,後來找到這個過程中一段很差的sql,具體sql不給出了,把實際的表縮小了10倍,造了相似的資料來模擬。也趁此機會測試一些數字。

測試的版本是1024,具體資訊和引數值:

SQL> select * from v$version;

 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod

PL/SQL Release 10.2.0.4.0 - Production

CORE    10.2.0.4.0      Production

TNS for Linux: Version 10.2.0.4.0 - Production

NLSRTL Version 10.2.0.4.0 - Production

 

SQL>

SQL> show parameter targ

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

archive_lag_target                   integer     0

db_flashback_retention_target        integer     1600

fast_start_io_target                 integer     0

fast_start_mttr_target               integer     0

pga_aggregate_target                 big integer 187M

sga_target                           big integer 564M

SQL>

 

SQL> show parameter cost

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

optimizer_index_cost_adj             integer     100

 

SQL> show parameters optimizer_dynamic_

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

optimizer_dynamic_sampling           integer     2

SQL>

 

SQL> show parameters file_multi

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_file_multiblock_read_count        integer     16

SQL>

 

create table t_test_a as select policy_code code , a.send_date dt

       from t_policy@core a where rownum < 100000;

建立測試表a,欄位code有少部分是空值,code和時間上面都有普通索引。

create table t_test_b as select policy_code code , a.send_date dt

       from t_policy@core a where rownum < 800000; 

建立測試表b,欄位code唯一,索引是普通索引,且為null able

update t_test_a a set a.code = '' where rownum < 1000;

commit;

create index ind_test_a_code on t_test_a(code);

create index ind_test_a_dt on t_test_a(dt);

create index ind_test_b_code on t_test_b(code);

 

先看幾個數值

SQL> select count(*) from t_test_a a where a.dt < date '2002-1-13';

 

  COUNT(*)

----------

       258

 

SQL>

SQL> select count(*) from t_test_a a where a.dt < date '2002-1-14';

 

  COUNT(*)

----------

       258

 

SQL> select count(*) from t_test_a a where a.dt < date '2002-1-15';

 

  COUNT(*)

----------

       854

 

SQL>

上面的資料,我們可以認為在2002-1-13這天沒有發生業務,而2002-1-14這天比較多。

 

分析表和索引,看看分析後的資訊:

SQL> select a.index_name,

  2         a.distinct_keys,

  3         a.leaf_blocks,

  4         a.clustering_factor,

  5         a.status,

  6         a.num_rows

  7    from dba_indexes a

  8   where a.table_name = 'T_TEST_A';

 

INDEX_NAME                     DISTINCT_KEYS LEAF_BLOCKS CLUSTERING_FACTOR STATUS     NUM_ROWS

------------------------------ ------------- ----------- ----------------- -------- ----------

IND_TEST_A_CODE                        40879         155             33425 VALID         40879

IND_TEST_A_DT                          18515         260             16451 VALID         97917

 

SQL> select a.index_name,

  2         a.distinct_keys,

  3         a.leaf_blocks,

  4         a.clustering_factor,

  5         a.status,

  6         a.num_rows

  7    from dba_indexes a

  8   where a.table_name = 'T_TEST_B';

 

INDEX_NAME                     DISTINCT_KEYS LEAF_BLOCKS CLUSTERING_FACTOR STATUS     NUM_ROWS

------------------------------ ------------- ----------- ----------------- -------- ----------

IND_TEST_B_CODE                       322435        1217            283993 VALID        322435

 

可以看看各個索引的factor值,基本上這些值也是可以從構建資料的過程中大致預見的。

 

SQL> alter system flush buffer_cache;

 

System altered.

 

SQL> select * from t_test_a a,t_test_b b

  2  where a.code = b.code

  3  and a.dt < date '2002-1-14'

  4  ;

 

CODE                 DT        CODE                 DT

-------------------- --------- -------------------- ---------

000001499157008      08-JAN-02 000001499157008      08-JAN-02

000001033450008      08-JAN-02 000001033450008      08-JAN-02

000001120964008      09-JAN-02 000001120964008      09-JAN-02

000001438262008      10-JAN-02 000001438262008      10-JAN-02

000001132065008      11-JAN-02 000001132065008      11-JAN-02

000001495927008      11-JAN-02 000001495927008      11-JAN-02

 

6 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2435190019

 

----------------------------------------------------------------------------------------------

| Id  | Operation                    | Name          | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |               |  3105 |   127K|   533  (50)| 00:00:01 |

|*  1 |  HASH JOIN                   |               |  3105 |   127K|   533  (50)| 00:00:01 |

|   2 |   TABLE ACCESS BY INDEX ROWID| T_TEST_A      |   258 |  5418 |    47   (0)| 00:00:01 |

|*  3 |    INDEX RANGE SCAN          | IND_TEST_A_DT |   258 |       |     4   (0)| 00:00:01 |

|   4 |   TABLE ACCESS FULL          | T_TEST_B      |   909K|    18M|   394  (44)| 00:00:01 |

----------------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("A"."CODE"="B"."CODE")

   3 - access("A"."DT"

 

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       2253  consistent gets

       2226  physical reads

          0  redo size

        906  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          6  rows processed

 

SQL>

 

 

SQL> alter system flush buffer_cache;

 

System altered.

 

SQL> select * from t_test_a a,t_test_b b

  2  where a.code = b.code

  3  and a.dt < date '2002-1-15'

  4  ;

 

CODE                 DT        CODE                 DT

-------------------- --------- -------------------- ---------

000001477714008      14-JAN-02 000001477714008      14-JAN-02

000001514461008      14-JAN-02 000001514461008      14-JAN-02

000001513712008      14-JAN-02 000001513712008      14-JAN-02

000001470378008      14-JAN-02 000001470378008      14-JAN-02

000001499157008      08-JAN-02 000001499157008      08-JAN-02

000001033450008      08-JAN-02 000001033450008      08-JAN-02

000001120964008      09-JAN-02 000001120964008      09-JAN-02

000001438262008      10-JAN-02 000001438262008      10-JAN-02

000001132065008      11-JAN-02 000001132065008      11-JAN-02

000001531818008      14-JAN-02 000001531818008      14-JAN-02

000001469522008      14-JAN-02 000001469522008      14-JAN-02

 

CODE                 DT        CODE                 DT

-------------------- --------- -------------------- ---------

000001492911008      14-JAN-02 000001492911008      14-JAN-02

000001495927008      11-JAN-02 000001495927008      11-JAN-02

 

13 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1839959879

 

-------------------------------------------------------------------------------

| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |          | 10276 |   421K|   540  (54)| 00:00:01 |

|*  1 |  HASH JOIN         |          | 10276 |   421K|   540  (54)| 00:00:01 |

|*  2 |   TABLE ACCESS FULL| T_TEST_A |   854 | 17934 |    54  (45)| 00:00:01 |

|   3 |   TABLE ACCESS FULL| T_TEST_B |   909K|    18M|   394  (44)| 00:00:01 |

-------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("A"."CODE"="B"."CODE")

   2 - filter("A"."DT"

              hh24:mi:ss'))

 

Note

-----

   - dynamic sampling used for this statement

 

 

Statistics

----------------------------------------------------------

         10  recursive calls

          0  db block gets

       2651  consistent gets

       2502  physical reads

          0  redo size

       1277  bytes sent via SQL*Net to client

        400  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          2  sorts (memory)

          0  sorts (disk)

         13  rows processed

SQL>

 

下面來具體看看執行計劃中的每一項,看看為什麼cbo優化器產生的執行計劃變化了:

 

SQL> explain plan for

  2  select * from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-14'

  5  ;

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a;

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           528       3425        264  262656473

1 HASH JOIN                                         0        528       3425        264  262656473

2 TABLE ACCESS      BY INDEX ROWID  T_TEST_A        1         42        258         42     385680

3 INDEX             RANGE SCAN      IND_TEST_A_DT   2          2        258          2      61043

4 TABLE ACCESS      FULL            T_TEST_B        1        394     909858        222  170748950

 

SQL>

注意到上面的這些資訊

使用的是hash join,小表使用時間欄位上的索引,range scan,全表掃描大表,cost394io_cost222Hash join操作之後的card3425,最後的cost528,表acard258

 

下面使用/*+ cardinality(a 17) */ hint來設定用以計算的card值,可以發現當a表的card足夠小的時候cbo有了一些變化,不再使用hash join而是使用nested loop了,而且很多值發生了很大的變化:

Card值減小了很多,io確是增加了近一倍的costcpu cost大大降低了(少了2位),兩個表都使用index range scan訪問。

通過index range scan訪問a表可以有258行返回值,但實際結果可以看到在與大表b join之後只有6行返回了。

 

 

SQL> explain plan for

  2  select /*+ cardinality(a 17) */* from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-14'

  5  ;

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a;

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           522        226        518    3972346

1 TABLE ACCESS      BY INDEX ROWID  T_TEST_B        0         28         13         28     210980

2 NESTED LOOPS                                      1        522        226        518    3972346

3 TABLE ACCESS      BY INDEX ROWID  T_TEST_A        2         42         17         42     385680

4 INDEX             RANGE SCAN      IND_TEST_A_DT   3          2        258          2      61043

5 INDEX             RANGE SCAN      IND_TEST_B_CODE 2          2         81          2      20893

 

6 rows selected.

 

 

SQL> rollback;

 

Rollback complete.

 

 

再來看看使用/*+ cardinality(a 18) */後的結果,只是增加了1card值,也已經產生了很大影響,查詢重新回到hash join的方式,b表全表掃描,cost變化不大,cpu也回到了最開始不加hint的時候的數量級,io也回到了原來的值。不過最終評估的card已經降低。

對比一下使用/*+ cardinality(a 17) *//*+ cardinality(a 18) */這兩個查詢,就可以發現,系統nested loopio評估較大,而hash join full相對小。

再看看系統統計資訊:

SQL> select a.sname,a.pname,trunc(a.pval1,2)

  2   from sys.aux_stats$ a  where a.sname = 'SYSSTATS_MAIN';

 

SNAME                          PNAME                          TRUNC(A.PVAL1,2)

------------------------------ ------------------------------ ----------------

SYSSTATS_MAIN                  CPUSPEEDNW                               576.86

SYSSTATS_MAIN                  IOSEEKTIM                                    10

SYSSTATS_MAIN                  IOTFRSPEED                                 4096

SYSSTATS_MAIN                  SREADTIM                                   1.78

SYSSTATS_MAIN                  MREADTIM                                    2.8

SYSSTATS_MAIN                  CPUSPEED                                    556

SYSSTATS_MAIN                  MBRC                                         16

SYSSTATS_MAIN                  MAXTHR                                 16664576

SYSSTATS_MAIN                  SLAVETHR

 

9 rows selected.

 

SQL>

可以看到MBRC16,多塊讀的時間比單塊讀並高不了多少。

 

 

SQL> explain plan for

  2  select /*+ cardinality(a 18) */* from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-14'

  5  ;

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a;

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           528        239        264  262620473

1 HASH JOIN                                         0        528        239        264  262620473

2 TABLE ACCESS      BY INDEX ROWID  T_TEST_A        1         42         18         42     385680

3 INDEX             RANGE SCAN      IND_TEST_A_DT   2          2        258          2      61043

4 TABLE ACCESS      FULL            T_TEST_B        1        394     909858        222  170748950

 

SQL>

 

 

SQL> rollback;

 

Rollback complete.

 

a(T_test_a)資料大概10萬行,14號之前行數是258行,15號之前的行數也只有854行。看看15號之前的查詢:

SQL> explain plan for

  2  select /*+ cardinality(a 17) */* from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-15'

  5  ;

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a;

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           536        226        506   29459528

1 TABLE ACCESS      BY INDEX ROWID  T_TEST_B        0         28         13         28     210980

2 NESTED LOOPS                                      1        536        226        506   29459528

3 TABLE ACCESS      FULL            T_TEST_A        2         56         17         30   25872862

4 INDEX             RANGE SCAN      IND_TEST_B_CODE 2          2         81          2      20893

 

SQL>

SQL> rollback;

 

Rollback complete.

 

SQL> explain plan for

  2  select /*+ cardinality(a 18) */* from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-15'

  5  ;

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a; 

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           542        239        252  288107654

1 HASH JOIN                                         0        542        239        252  288107654

2 TABLE ACCESS      FULL            T_TEST_A        1         56         18         30   25872862

3 TABLE ACCESS      FULL            T_TEST_B        1        394     909858        222  170748950

 

SQL>

 

SQL> rollback

  2  ;

 

Rollback complete.

 

分析一下物件統計資訊,再看看

 

SQL> explain plan for

  2  select * from t_test_a a,t_test_b b

  3  where a.code = b.code

  4  and a.dt < date '2002-1-15';

 

Explained.

 

SQL> select substr(a.id,1,1) id,

  2         substr(a.operation,1,17) operation,

  3         substr(a.options,1,15) options,

  4         substr(a.object_name,1,15) object_name,

  5         substr(a.parent_id,1,1) p_id,

  6         a.cost,

  7         a.cardinality card,

  8         a.io_cost,

  9         a.cpu_cost

 10    from plan_table a;

 

I OPERATION         OPTIONS         OBJECT_NAME     P       COST       CARD    IO_COST   CPU_COST

- ----------------- --------------- --------------- - ---------- ---------- ---------- ----------

0 SELECT STATEMENT                                           468        381        252  214442833

1 HASH JOIN                                         0        468        381        252  214442833

2 TABLE ACCESS      FULL            T_TEST_A        1         53        381         30   23123220

3 TABLE ACCESS      FULL            T_TEST_B        1        381     322435        222  158521620

 

SQL>

 

 

下面是14號之前的10046tracefile

 

********************************************************************************

count    = number of times OCI procedure was executed

cpu      = cpu time in seconds executing

elapsed  = elapsed time in seconds executing

disk     = number of physical reads of buffers from disk

query    = number of buffers gotten for consistent read

current  = number of buffers gotten in current mode (usually for update)

rows     = number of rows processed by the fetch or execute call

********************************************************************************

 

select * from t_test_a a,t_test_b b

where a.code = b.code

and a.dt < date '2002-1-14'

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch       13      0.41       0.40       2493       2513          0         167

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total       15      0.42       0.40       2493       2513          0         167

 

Misses in library cache during parse: 1

Optimizer mode: ALL_ROWS

Parsing user id: 61 

 

Rows     Row Source Operation

-------  ---------------------------------------------------

    167  HASH JOIN  (cr=2513 pr=2493 pw=0 time=46167 us)

    167   TABLE ACCESS FULL T_TEST_A (cr=282 pr=279 pw=0 time=1967 us)

 322435   TABLE ACCESS FULL T_TEST_B (cr=2231 pr=2214 pw=0 time=1935491 us)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                      13        0.00          0.00

  db file sequential read                         2        0.00          0.00

  db file scattered read                        176        0.00          0.10

  SQL*Net message from client                    13        0.00          0.02

********************************************************************************

 

再看看使用nlhint之後的執行資訊:

*******************************************************************************

count    = number of times OCI procedure was executed

cpu      = cpu time in seconds executing

elapsed  = elapsed time in seconds executing

disk     = number of physical reads of buffers from disk

query    = number of buffers gotten for consistent read

current  = number of buffers gotten in current mode (usually for update)

rows     = number of rows processed by the fetch or execute call

********************************************************************************

 

select /*+ use_nl(a,b)*/* from t_test_a a,t_test_b b

where a.code = b.code

and a.dt < date '2002-1-14'

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch       13      0.08       0.08        296        671          0         167

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total       15      0.08       0.08        296        671          0         167

 

Misses in library cache during parse: 0

Optimizer mode: ALL_ROWS

Parsing user id: 61 

 

Rows     Row Source Operation

-------  ---------------------------------------------------

    167  TABLE ACCESS BY INDEX ROWID T_TEST_B (cr=671 pr=296 pw=0 time=9155 us)

    335   NESTED LOOPS  (cr=653 pr=289 pw=0 time=612607 us)

    167    TABLE ACCESS FULL T_TEST_A (cr=294 pr=279 pw=0 time=5071 us)

    167    INDEX RANGE SCAN IND_TEST_B_CODE (cr=359 pr=10 pw=0 time=8836 us)(object id 69411)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                      13        0.00          0.00

  db file sequential read                        18        0.00          0.00

  db file scattered read                         27        0.00          0.02

  SQL*Net message from client                    13        4.82          4.84

********************************************************************************

 

可以看到無論是cpu,還是耗時,還是磁碟讀,邏輯讀使用nl都要比使用hash join小的多。

 

接著對錶a做了直方圖之後也沒有什麼起色。

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1839959879

 

-------------------------------------------------------------------------------

| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |          |   369 | 10332 |   468  (47)| 00:00:01 |

|*  1 |  HASH JOIN         |          |   369 | 10332 |   468  (47)| 00:00:01 |

|*  2 |   TABLE ACCESS FULL| T_TEST_A |   369 |  5166 |    53  (44)| 00:00:01 |

|*  3 |   TABLE ACCESS FULL| T_TEST_B |   322K|  4408K|   381  (42)| 00:00:01 |

-------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - access("A"."CODE"="B"."CODE")

   2 - filter("A"."CODE" IS NOT NULL AND "A"."DT"

              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

   3 - filter("B"."CODE" IS NOT NULL)

 

 

Statistics

----------------------------------------------------------

          1  recursive calls

          0  db block gets

       2513  consistent gets

       2493  physical reads

          0  redo size

      10052  bytes sent via SQL*Net to client

        521  bytes received via SQL*Net from client

         13  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

        167  rows processed

 

SQL>

 

這裡看到幾處謂詞中加上了is not nullT_test_bcard值減小了很多,因為有很多空值,這個是前面沒有注意的,刪之。

再看效果:

********************************************************************************

 

select * from t_test_a a,t_test_b b

where a.code = b.code

and a.dt < date '2002-1-14'

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.00       0.00          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch       13      0.56       0.54       2493       2513          0         167

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total       15      0.56       0.54       2493       2513          0         167

 

Misses in library cache during parse: 0

Optimizer mode: ALL_ROWS

Parsing user id: 61 

 

Rows     Row Source Operation

-------  ---------------------------------------------------

    167  HASH JOIN  (cr=2513 pr=2493 pw=0 time=106404 us)

    167   TABLE ACCESS FULL T_TEST_A (cr=282 pr=279 pw=0 time=20395 us)

 322435   TABLE ACCESS FULL T_TEST_B (cr=2231 pr=2214 pw=0 time=2580871 us)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                      13        0.00          0.00

  db file sequential read                         2        0.00          0.00

  db file scattered read                        176        0.00          0.21

  SQL*Net message from client                    13        4.44          4.45

********************************************************************************

 

********************************************************************************

 

select /*+ use_nl(a,b) */* from t_test_a a,t_test_b b

where a.code = b.code

and a.dt < date '2002-1-14'

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.02       0.02          0          0          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch       13      0.08       0.08        296        671          0         167

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total       15      0.11       0.11        296        671          0         167

 

Misses in library cache during parse: 1

Optimizer mode: ALL_ROWS

Parsing user id: 61 

 

Rows     Row Source Operation

-------  ---------------------------------------------------

    167  TABLE ACCESS BY INDEX ROWID T_TEST_B (cr=671 pr=296 pw=0 time=11934 us)

    335   NESTED LOOPS  (cr=653 pr=289 pw=0 time=726477 us)

    167    TABLE ACCESS FULL T_TEST_A (cr=294 pr=279 pw=0 time=5517 us)

    167    INDEX RANGE SCAN IND_TEST_B_CODE (cr=359 pr=10 pw=0 time=9576 us)(object id 69415)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                      13        0.00          0.00

  db file sequential read                        18        0.00          0.00

  db file scattered read                         27        0.00          0.02

  SQL*Net message from client                    13        3.45          3.47

********************************************************************************

 

曉得不是最優的情況,但是還是對cbo的具體計算方法不解,待後續分析求解。。。

 

 

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-673191/,如需轉載,請註明出處,否則將追究法律責任。

相關文章