ºìÁªLinuxÃÅ»§
Linux°ïÖú

ºÎʱOracleʹÓð󶨱äÁ¿ÐÔÄÜ·´¶ø¸ü²î

·¢²¼Ê±¼ä:2007-02-01 00:30:23À´Ô´:ºìÁª×÷Õß:Mischievous
¡¡¡¡µ±ÎÒÔÚ×öÅàѵʱ£¬ÔÚ½âÊͰ󶨱äÁ¿µÄºÃ´¦Ê±£¬´ó¼Ò¶¼±È½ÏÈÝÒ×Àí½â¡£µ«ÊÇ£¬¶ÔÓÚ²¢²»ÊÇÈκÎʱºò°ó¶¨±äÁ¿¶¼ÊÇ×îÓŵġ£ÕâÒ»µãºÜ¶àÈ˲»ÊǺÍÀí½â¡£ÏÂÃæ¾ÍÌÖÂÛÒ»ÏÂÔÚʲôʱºò»á³öÏְ󶨱äÁ¿»áʹÐÔÄܱä²î¡£

¡¡¡¡É¨Ãè³É±¾ºÍOPTIMIZER_INDEX_COST_ADJ

¡¡¡¡ÎÒÃÇÖªµÀ£¬ÔÚCBOģʽÏ£¬Oracle»á¼ÆËã¸÷¸ö·ÃÎÊ·¾¶µÄ´ú¼Û£¬²ÉÓÃ×îС´ú¼ÛµÄ·ÃÎÊ·¾¶×÷ΪÓï¾äµÄÖ´Ðмƻ®¡£¶ø¶ÔÓÚË÷ÒýµÄ·ÃÎÊ´ú¼ÛµÄ¼ÆË㣬ÐèÒª¸ù¾ÝÒ»¸öϵͳ²ÎÊýOPTIMIZER_INDEX_COST_ADJÀ´×ª»»ÎªÓëÈ«±íɨÃè´ú¼ÛµÈ¼ÛµÄÒ»¸öÖµ¡£ÕâÊÇʲôÒâ˼ÄØ£¿ÎÒÃÇÏÈÉÔ΢½âÊÍÒ»ÏÂÕâ¸ö²ÎÊý£ºOPTIMIZER_INDEX_COST_ADJ¡£ËüµÄÖµÊÇÒ»¸ö°Ù·Ö±È£¬Ä¬ÈÏÊÇ100£¬È¡Öµ·¶Î§ÊÇ1¡«10000¡£µ±¹ÀËãË÷ÒýɨÃè´ú¼Ûʱ£¬»á½«Ë÷ÒýµÄԭʼ´ú¼ÛÖµ³ËÒÔÕâ¸ö°Ù·Ö±È£¬½«»»ËãºóµÄÖµ×÷ΪÓëÈ«±íɨÃè´ú¼Û±È½ÏµÄÖµ¡£Ò²¾ÍÊÇ˵£¬µ±Õâ¸öֵΪ100ʱ£¬¼ÆËã³öµÄË÷ÒýɨÃè´ú¼Û¾ÍÊÇËüµÄԭʼ´ú¼Û£º

ÒýÓÃ:
COST_COM = COST_ORG * OPTIMIZER_INDEX_COST_ADJ/100


¡¡¡¡¿´ÒÔÏÂÀý×Ó£º

ÒýÓÃ:
SQL> create table T_PEEKING (a NUMBER, b char(1), c char(2000));

Table created.

SQL>
SQL> create index T_PEEKING_IDX1 on T_PEEKING(b);

Index created.


SQL> begin
2 for i in 1..1000 loop
3 insert into T_PEEKING values (i, 'A', i);
4 end loop;
5
6 insert into T_PEEKING values (1001, 'B', 1001);
7 insert into T_PEEKING values (1002, 'B', 1002);
8 insert into T_PEEKING values (1003, 'C', 1003);
9
10 commit;
11 end;
12 /

PL/SQL procedure successfully completed.


¡¡¡¡×¢Ò⣬ÎÒÃǸøË÷Òý×Ö¶ÎB²åÈëµÄÖµÖÐÖ»ÓÐ3¸ödistinctÖµ£¬¼Ç¼ÊýÊÇ1003£¬ËüµÄ¼¯µÄÊƺܸߣ¨1003/3£©=334¡£

ÒýÓÃ:
SQL>
SQL> analyze table T_PEEKING compute
statistics for table for all indexes for all indexed columns;

Table analyzed.

SQL>


¡¡¡¡ÎÒÃÇ¿´ÏÂË÷ÒýɨÃèµÄ´ú¼ÛÊǶàÉÙ£º

ÒýÓÃ:
SQL> show parameter OPTIMIZER_INDEX_COST_ADJ

NAME TYPE VALUE
------------------------------------ ----------- ------
optimizer_index_cost_adj integer 100

SQL> delete from plan_table;

0 rows deleted.

SQL>

SQL> explain plan for select
/*+index(a T_PEEKING_IDX1)*/ * from T_PEEKING a where b = :V;

Explained.

SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
3 Plan_Table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id
7 ;

Query
Plan_Table
-----------------------------------------------------
SELECT STATEMENT Cost=113
TABLE ACCESS BY INDEX ROWID T_PEEKING
INDEX RANGE SCAN T_PEEKING_IDX1

SQL>


¡¡¡¡ÔÙ¿´È«±íɨÃèµÄ´ú¼ÛÊǶàÉÙ£º

ÒýÓÃ:
SQL> delete from plan_table;

3 rows deleted.

SQL>
SQL> explain plan for select
/*+full(a)*/ * from T_PEEKING a where b = :V;

Explained.

SQL>
SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
3 Plan_Table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id
7 ;

Query
Plan_Table
----------------------------------------------------
SELECT STATEMENT Cost=75
TABLE ACCESS FULL T_PEEKING

SQL>


¡¡¡¡Õâʱ£¬ÎÒÃÇ¿ÉÒÔ¼ÆËãµÃ³öÈÃÓÅ»¯Æ÷ʹÓÃË÷Òý£¨ÎÞÌáʾǿÖÆ£©µÄOPTIMIZER_INDEX_COST_ADJÖµÓ¦¸Ã< ROUND(COST_FTS/COST_IDX*100) = ROUND(75/113*100) = 66£¬¶ø´óÓÚ66Ôò»áʹÓÃÈ«±íɨÃ裺

ÒýÓÃ:
SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=67;

System altered.

SQL>
SQL> delete from plan_table;

2 rows deleted.

SQL>
SQL> explain plan for select * from T_PEEKING a where b = :V;

Explained.

SQL>
SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
3 Plan_Table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id;

Query
Plan_Table
-----------------------------------------------------------------
SELECT STATEMENT Cost=75
TABLE ACCESS FULL T_PEEKING

SQL>
SQL>
SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=66;

System altered.

SQL>
SQL> delete from plan_table;

2 rows deleted.

SQL>
SQL> explain plan for select * from T_PEEKING a where b = :V;

Explained.

SQL>
SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
3 Plan_Table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id;

Query
Plan_Table
---------------------------------------------------------
SELECT STATEMENT Cost=75
TABLE ACCESS BY INDEX ROWID T_PEEKING
INDEX RANGE SCAN T_PEEKING_IDX1
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 2 ÌõÆÀÂÛ

  1. Mischievous ÓÚ 2007-02-01 00:32:28·¢±í:

    ¡¡¡¡ÓÃTkprof´¦ÀíÉú³ÉµÄtraceÎļþ¡£ÒòΪÔÚ´æÔڰ󶨱äÁ¿¿úÊÓʱ£¬autotrace»òÕßexplain plan¿ÉÄܲ»»áÏÔʾÕýÈ·µÄ²éѯ¼Æ»®£¬ÐèÒªTkprofÀ´´¦Àísql trace¡£

    ÒýÓÃ:
    tkprof fuyuncat_ora_5352.trc aaa.txt


    ¡¡¡¡´ËʱOPTIMIZER_INDEX_COST_ADJÊÇ60£¬¸ù¾ÝÉÏÃæµÄ½áÂÛ£¬Ëƺõ²éѯ¼Æ»®Ó¦¸ÃÑ¡ÔñɨÃèË÷Òý¡£µ«ÊÇ£¬ÕâÀï¸ø°ó¶¨±äÁ¿¸³ÁËÖµ"A"£¬Õâʱ£¬ÓÅ»¯Æ÷»á¡°¿úÊÓ¡±µ½Õâ¸öÖµ£¬²¢ÇÒÔÚ¼ÆËãɨÃè³É±¾Ê±°´ÕÕÕâ¸öÖµµÄ³É±¾À´¼ÆËã¡£Òò´Ë£¬µÃ³öµÄ²éѯ¼Æ»®ÊÇÈ«±íɨÃ裬¶ø²»ÊÇɨÃèË÷Òý£¬¿¿Tkprof·ÖÎöµÄ½á¹û£º

    ÒýÓÃ:
    select *
    from
    T_PEEKING a where b = :V


    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 68 0.01 0.07 0 406 0 1000
    ------- ------ -------- ---------- ---------- ---------- ---------- ----------
    total 70 0.01 0.08 0 406 0 1000

    Misses in library cache during parse: 1
    Optimizer mode: CHOOSE
    Parsing user id: SYS

    Rows Row Source Operation
    ------- ---------------------------------------------------
    1000 TABLE ACCESS FULL T_PEEKING (cr=406 pr=0 pw=0 time=5052 us)


    ¡¡¡¡µ«ÊÇ£¬°ó¶¨±äÁ¿¿úÊÓ¶ÔÒ»ÌõÓï¾äÖ»»áʹÓÃÒ»´Î¡£¾ÍÊÇ˵£¬ÔÚµÚÒ»´Î½âÎöÓï¾äʱ£¬½«°ó¶¨±äÁ¿Öµ¿¼ÂǽøÈ¥¼ÆËã³É±¾Éú³É²éѯ¼Æ»®¡£ÒÔºóÔÚÖ´ÐиÃÓï¾äʱ¶¼²ÉÓÃÕâ¸ö²éѯ¼Æ»®£¬¶ø²»ÔÙ¿¼ÂÇÒÔºó°ó¶¨±äÁ¿µÄÖµÊÇʲôÁË¡£

    ÒýÓÃ:
    SQL> conn sys/sys as sysdba
    Connected.
    SQL>
    SQL>
    SQL> set autot trace
    SQL>
    SQL> alter session set sql_trace = true;

    Session altered.

    SQL>
    SQL> var v char(1)
    SQL>
    SQL> exec :v := 'B';

    PL/SQL procedure successfully completed.

    SQL>
    SQL> select * from T_PEEKING a where b = :V;

    1000 rows selected.

    SQL>
    SQL> alter session set sql_trace = false;

    Session altered.


    ¡¡¡¡ÔÙÓÃTkprof·ÖÎöÉú³ÉµÄtraceÎļþ£¬¿´µ½¾¡¹ÜÕâÀïµÄÖµÊÇ"B"£¬Ñ¡ÔñË÷ÒýɨÃè»á¸üÓÅ£¬µ«·ÖÎö½á¹ûÖвéѯ¼Æ»®»¹ÊÇʹÓÃÈ«±íɨÃ裺

    ÒýÓÃ:
    select *
    from
    T_PEEKING a where b = :V


    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 2 0.00 0.00 0 340 0 2
    ------- ------ -------- ---------- ---------- ---------- ---------- ----------
    total 4 0.00 0.00 0 340 0 2

    Misses in library cache during parse: 0
    Optimizer mode: CHOOSE
    Parsing user id: SYS

    Rows Row Source Operation
    ------- ---------------------------------------------------
    2 TABLE ACCESS FULL T_PEEKING (cr=340 pr=0 pw=0 time=1005 us)


    ¡¡¡¡Òò´Ë£¬ÕâÖÖÇé¿öÏÂʹÓð󶨱äÁ¿Ò²»áµ¼ÖÂÎÞ·¨Ñ¡Ôñ×îÓŵIJéѯ¼Æ»®¡£

    ¡¡¡¡×ÛÉÏËùÊö£¬ÎÒÃÇ¿ÉÒԵóöÒ»¸ö½áÂÛ£ºÔÚ¶Ô½¨ÓÐË÷ÒýµÄ×ֶΣ¨°üÀ¨×ֶμ¯£©£¬ÇÒ×ֶΣ¨¼¯£©µÄ¼¯µÄÊƷdz£´óʱ£¬Ê¹Óð󶨱äÁ¿¿ÉÄܻᵼÖ²éѯ¼Æ»®´íÎó£¬Òò¶ø»áʹ²éѯЧÂʷdz£µÍ¡£

  2. Mischievous ÓÚ 2007-02-01 00:31:21·¢±í:

    ¡¡¡¡¿ÉÒÔ¿´³ö£¬ÔÚʹÓð󶨱äÁ¿Ê±£¬²ÎÊýOPTIMIZER_INDEX_COST_ADJ¶ÔÓÚÊÇ·ñÑ¡ÔñË÷Òý»áÓÐÖØÒªµÄÓ°Ïì¡£ÕâÀïÎÒÃÇÔÝÇÒ²»ÌÖÂÛË÷ÒýɨÃèµÄԭʼ³É±¾ÊÇÈçºÎ¼ÆËãµÃ³öµÄ¡£µ«ÊÇÓÐÒ»µãºÜÖØÒª£¬ÔÚʹÓð󶨱äÁ¿Ê±£¬¼ÆËã³öµÄ³É±¾ÊÇƽ¾ù³É±¾¡£ÔÚÎÒÃÇÉÏÃæµÄÀý×ÓÖУ¬×Ö¶ÎBµÄÖµÖ»ÓÐ3¸ö£º"A"¡¢"B"¡¢"C"£¬ÆäÖÐA×î¶à£¬1003ÐÐÖÐÓÐ1000ÐС£Òò´Ë£¬ÔÚË÷ÒýÉÏɨÃèֵΪA¼Ç¼µÄ³É±¾Îª1000/1003 * Ë÷ÒýȫɨÃè³É±¾ ¡ÖË÷ÒýȫɨÃè³É±¾£¬ÎÒÃÇ¿´ÏÂËüµÄ³É±¾ÊǶàÉÙ£º

    ÒýÓÃ:
    SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=100;

    System altered.

    SQL>
    SQL> delete from plan_table;

    2 rows deleted.

    SQL>
    SQL> explain plan for select
    /*+index(a T_PEEKING_IDX1)*/* from T_PEEKING a where b = 'A';

    Explained.

    SQL>
    SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
    2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
    3 Plan_Table"
    4 from plan_table
    5 start with id = 0
    6 connect by prior id = parent_id;

    Query
    Plan_Table
    --------------------------------------------------------------
    SELECT STATEMENT Cost=336
    TABLE ACCESS BY INDEX ROWID T_PEEKING
    INDEX RANGE SCAN T_PEEKING_IDX1


    ¡¡¡¡¿ÉÒÔ¿´µ½£¬ËüµÄ³É±¾ÊÇ336¡£Òò´ËË÷ÒýµÄƽ¾ù³É±¾ÊÇ(336 * 1003/1000) / 3 ¡Ö 113£¬Ò²¾ÍÊÇʹÓð󶨱äÁ¿Ê¹µÄ³É±¾¡£¶øɨÃèÆäËüÁ½¸öÖµ"B"ºÍ"A"ʱ´ú¼Û¾Í·Ç³£Ð¡¡£

    ÒýÓÃ:
    SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=100;

    System altered.

    SQL>
    SQL> delete from plan_table;

    3 rows deleted.

    SQL>
    SQL> explain plan for select
    /*+index(a T_PEEKING_IDX1)*/* from T_PEEKING a where b = 'B';

    Explained.

    SQL>
    SQL> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
    2 object_name||' '||decode(id, 0, 'Cost='||position) "Query
    3 Plan_Table"
    4 from plan_table
    5 start with id = 0
    6 connect by prior id = parent_id;

    Query
    Plan_Table
    ---------------------------------------------------------------
    SELECT STATEMENT Cost=2
    TABLE ACCESS BY INDEX ROWID T_PEEKING
    INDEX RANGE SCAN T_PEEKING_IDX1


    ¡¡¡¡ÒòΪ¼ÆËãµÄ³É±¾ÊÇƽ¾ù³É±¾£¨Ïà¶Ôʵ¼ÊɨÃèij¸öÖµµÄ³É±¾£¬Æ½¾ù³É±¾¸ü½Ó½üÈ«±íɨÃè³É±¾£©£¬Òò´ËÔÚ´´½¨²éѯ¼Æ»®Ê±£¬Ê¹Óð󶨱äÁ¿½«¸ü¼ÓÈÝÒ×Êܵ½²ÎÊýOPTIMIZER_INDEX_COST_ADJÓ°Ï죬ÌرðÊÇÉÏÃæµÄÕâÖÖÇé¿ö£¨¼´Ë÷Òý×ֶεļ¯µÄÊƷdz£¸ßʱ£©Ï£¬Æ½¾ù´ú¼ÛÓëʵ¼ÊɨÃèij¸öÖµ´ú¼ÛÏà²î·Ç³£Ô¶¡£ÕâÖÖÇé¿öÏ£¬OPTIMIZER_INDEX_COST_ADJ¶Ô²»Ê¹Óð󶨱äÁ¿²éѯӰÏì¾Í·Ç³£Ð¡£¨ÒòΪË÷Òý´ú¼Û²»ÊDZÈÈ«±íɨÃè³É±¾´óºÜ¶à¾ÍÊÇСºÜ¶à£©£¬²»¹ÜɨÃèÄĸöÖµ£¬²»Ê¹Óð󶨱äÁ¿½«¸ü¼ÓÈÝÒ×Ñ¡Ôñµ½ºÏÀíµÄ²éѯ¼Æ»®¡£

    ¡¡¡¡°ó¶¨±äÁ¿¿úÊÓ

    ¡¡¡¡ÔÚÁ˽âÁ˲ÎÊýOPTIMIZER_INDEX_COST_ADJµÄ×÷Óúó¡£ÔÙÁ˽âÒ»¸ö¶Ô²éѯ¼Æ»®£¬ÌرðÊÇʹÓð󶨱äÁ¿Ê±»á²úÉúÖØ´óÓ°ÏìµÄÌØÐÔ£º°ó¶¨±äÁ¿¿úÊÓ£¨Bind Variables Peeking£©¡£

    ¡¡¡¡°ó¶¨±äÁ¿¿úÊÓÊÇ9iÒÔºóµÄÒ»¸öÐÂÌØÐÔ¡£ËüʹCBOÓÅ»¯Æ÷ÔÚ¼ÆËã·ÃÎÊ´ú¼Ûʱ£¬½«°ó¶¨±äÁ¿´«ÈëµÄÖµ¿¼ÂǽøÈ¥£¬´Ó¶ø¼ÆËã³ö¸üºÏÀíµÄ³É±¾£¨·ñÔò£¬½«»á¼ÆËãƽ¾ù³É±¾£©¡£¿´ÏÂÃæÀý×Ó£º

    ÒýÓÃ:
    SQL> conn sys/sys as sysdba
    Connected.
    SQL>
    SQL> alter system set OPTIMIZER_INDEX_COST_ADJ=60;

    System altered.

    SQL> analyze table T_PEEKING compute
    statistics for table for all indexes for all indexed columns;

    Table analyzed.

    SQL>
    SQL> set autot trace
    SQL>
    SQL> alter session set sql_trace = true;

    Session altered.

    SQL>
    SQL> var v char(1)
    SQL>
    SQL> exec :v := 'A';

    PL/SQL procedure successfully completed.

    SQL>
    SQL> select * from T_PEEKING a where b = :V;

    1000 rows selected.

    SQL>
    SQL> alter session set sql_trace = false;

    Session altered.