首页 > 代码库 > CBO之Full Table Scan - FTS算法

CBO之Full Table Scan - FTS算法

转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/44261859

***********************************************
    一、CBO之Full Table Scan - FTS算法
*********************************************
**

1、建表
SQL> create table gyj_t1(id int,name varchar2(20));

Table created.

2、插入10万行数据
SQL> begin
  2   for i in 1 .. 100000 loop
  3    insert into gyj_t1 values(i,lpad(‘gyj‘,‘10‘,‘j‘)||i);
  4    commit;
  5  end loop;
  6  end;
  7  /

PL/SQL procedure successfully completed.


3、收集统计信息
SQL> BEGIN
  2  DBMS_STATS.GATHER_TABLE_STATS(
  3  ownname => ‘GYJ‘,
  4  tabname => ‘GYJ_T1‘,
  5  estimate_percent => 100,
  6  method_opt => ‘for all columns size 1‘,
  7  degree => DBMS_STATS.AUTO_DEGREE,
  8  cascade=>TRUE
  9  );
 10  END;
 11  /

PL/SQL procedure successfully completed.

/

4、运行SQL,生成运行计划。即能看到例如以下全表扫描的成本
SQL> set autot traceonly;
SQL> select count(*) from gyj_t1;


Execution Plan
----------------------------------------------------------
Plan hash value: 2553183190

---------------------------------------------------------------------
| Id  | Operation          | Name   | Rows  | Cost (%CPU)| Time     |
---------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |     1 |    84   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |        |     1 |            |          |
|   2 |   TABLE ACCESS FULL| GYJ_T1 |   100K|    84   (2)| 00:00:02 |
---------------------------------------------------------------------


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        373  consistent gets
          0  physical reads
          0  redo size
        526  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)

5、全表扫描CBO公式
FTS Cost = I/O Cost + CPU Cost
I/O Cost = 1 + CEIL(#MRds * (mreadtim / sreadtim))
#MRds = #Blks / MBRC
CPU Cost = ROUND(#CPUCycles / cpuspeed / 1000 / sreadtim)

6、#MRds
#MRds = #Blks / MBRC
(1)#Blks
SQL> select blocks from dba_tables where owner=‘GYJ‘ and table_name=‘GYJ_T1‘;

    BLOCKS
----------
       370

(2)多块读的參数
SQL> show parameter db_file_multiblock_read_count

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count        integer     16


(3)#MRds
SQL> select 370/16 from dual;

   370/16
----------
 23.125

7、mreadtim


SQL> select (select pval1 from sys.aux_stats$ where pname = ‘IOSEEKTIM‘) +
  2         (select value
  3             from v$parameter
  4   where name = ‘db_file_multiblock_read_count‘) *
  5  (select value from v$parameter where name = ‘db_block_size‘) /
  6   (select pval1 from sys.aux_stats$ where pname = ‘IOTFRSPEED‘) "mreadtim"
  7   from dual;

  mreadtim
----------
        42

即mreadtim=ioseektim+db_file_multiblock_count*db_block_size/iotftspeed
        =10+16*8192/4096=42

8、sreadtim
SQL> select (select pval1 from sys.aux_stats$ where pname = ‘IOSEEKTIM‘) +
  2         (select value from v$parameter where name = ‘db_block_size‘) /
  3         (select pval1 from sys.aux_stats$ where pname = ‘IOTFRSPEED‘) "sreadtim"
  4    from dual;

  sreadtim
----------
        12
即 sreadtim=ioseektim+db_block_size/iotfrspeed
        =10+8192/4096=12


(9)#CPUCycles

explain plan for select count(*) from GYJ_T1;
SQL> select cpu_cost from plan_table;
CPU_COST
----------
  17634933

   
(10)CPUSPEEDNW
SQL> select pname, pval1 from sys.aux_stats$ where sname=‘SYSSTATS_MAIN‘;

PNAME                               PVAL1
------------------------------ ----------
CPUSPEEDNW                     2894.14695
IOSEEKTIM                              10
IOTFRSPEED                           4096
SREADTIM
MREADTIM
CPUSPEED
MBRC
MAXTHR
SLAVETHR

(11)隐含參数:
SQL> @?/rdbms/admin/show_para
Enter value for p: table_scan_cost
old  12:     AND upper(i.ksppinm) LIKE upper(‘%&p%‘)
new  12:     AND upper(i.ksppinm) LIKE upper(‘%table_scan_cost%‘)

P_NAME                                   P_DESCRIPTION                                      P_VALUE                          ISDEFAULT ISMODIFIED ISADJ
---------------------------------------- -------------------------------------------------- ------------------------------ --------- ---------- -----
_table_scan_cost_plus_one                bump estimated full table scan and index ffs cost  TRUE    TRUE      FALSE       FALSE
                                         by one


(12)IO成本
I/O Cost = 1 + CEIL(#MRds * (mreadtim / sreadtim))
/O Cost = 1 + CEIL(23.125 * ((10+16*8192/4096) / (10+8192/4096)))
SQL> select 1 + CEIL(23.125 * ((10+16*8192/4096) / (10+8192/4096))) from dual;

1+CEIL(23.125*((10+16*8192/4096)/(10+8192/4096)))
-------------------------------------------------
                                           82

(13)CPU成本
CPU Cost = ROUND(#CPUCycles / cpuspeed / 1000 / sreadtim)
           ROUND(17634933/ 2894.14695 / 1000 / (10+8192/4096))=1



CBO之Full Table Scan - FTS算法