欢迎投稿

今日深度:

计算cost--全表扫描,计算cost--表扫描

计算cost--全表扫描,计算cost--表扫描


下面教大家如何手工算出oracle执行计划中的cost值。

成本的计算方式如下:
Cost = (
       #SRds * sreadtim +
       #MRds * mreadtim +
       CPUCycles / cpuspeed
       ) / sreadtime


#SRds - number of single block reads 单块读个数     
#MRds - number of multi block reads  多块读个数     
#CPUCyles - number of CPU cycles     CPU时钟周期数  


sreadtim - single block read time    单块读耗时(单位milliseconds 毫秒,1000毫秒等于1秒
mreadtim - multi block read time     多块读耗时(单位milliseconds 毫秒,1000毫秒等于1秒)
cpuspeed - CPU cycles per second     CPU频率(单位MHZ)   单位是秒


mreadtim=ioseektim+db_file_multiblock_count*db_block_size/iotftspeed 
sreadtim=ioseektim+db_block_size/iotfrspeed  

@脚本将在后面给出

SQL>create table aaa as select * from dba_objects where rownum<=10000;

SQL> conn scott/tiger 
Connected.
SQL> alter system set db_file_multiblock_read_count=16;
System altered.
SQL> explain plan for select count(*) from aaa;
Explained.

SQL> @getplan
'general,outline,starts'
Enter value for plan type:
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 977873394
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |    33   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| AAA  | 10000 |    33   (0)| 00:00:01 |
-------------------------------------------------------------------

SQL> @getmreadtime    --一次多块读的时间
  mreadtim
----------
        42
1 row selected.
SQL> @getsreadtime   --一次单块读的时间
  sreadtim
----------
        12
1 row selected.
SQL> @getcputime   --消耗的cpu的时间
    cputim
----------
.928809822
1 row selected.
SQL> @getmreadnum             --scott.aaa全表扫描是多块读需要的次数
Enter value for owner: scott
Enter value for table_name: aaa
  MREADNUM
----------
    8.8125
1 row selected.
SQL> @gettablecost           --计算出成本
Enter value for mreadtime: 42
Enter value for mreadnum:  8.8125
Enter value for cputime: 0.928809822
Enter value for sreadtime: 12

(42*8.8125+0.928809822)/12
--------------------------
                30.9211508
1 row selected.
conn /as sysdba
@getparam_imp                   --查隐含参数
Enter value for parameter_name:_table_scan_cost_plus_one
_table_scan_cost_plus_one                          TRUE

SQL> conn scott/tiger 
Connected.
SQL> alter session set "_table_scan_cost_plus_one"=false;
Session altered.
SQL> explain plan for select count(*) from aaa;
Explained.
SQL> @getplan
'general,outline,starts'
Enter value for plan type:
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 977873394


-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |    32   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| AAA  | 10000 |    32   (0)| 00:00:01 |
-------------------------------------------------------------------



--以下是@脚本

--@getmreadtime
select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
       (select value from v$parameter where name = 'db_file_multiblock_read_count') * 
       (select value from v$parameter where name = 'db_block_size') / 
       (select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "mreadtim"
   from dual;


--@getsreadtime
select (select pval1 from sys.aux_stats$ where pname = 'IOSEEKTIM') +
       (select value from v$parameter where name = 'db_block_size') /
       (select pval1 from sys.aux_stats$ where pname = 'IOTFRSPEED') "sreadtim"
  from dual;  


--@getcputime
select (select distinct cpu_cost from plan_table where cpu_cost is not null)/
       (select pval1 from sys.aux_stats$ where sname='SYSSTATS_MAIN' and pname='CPUSPEEDNW')/
       1000 "cputim"
  from dual;


--@getmreadnum
select (select BLOCKS from dba_tables where owner=upper('&owner') and table_name=upper('&table_name'))/
       (select value from v$parameter where name = 'db_file_multiblock_read_count') "mreadnum"
  from dual;


@gettablecost
select (&mreadtime*&mreadnum+&cputime)/&sreadtime from dual;


--@getparam_imp  
SELECT nam.ksppinm NAME, val.ksppstvl VALUE  
  FROM sys.x$ksppi nam, sys.x$ksppsv val  
 WHERE nam.indx = val.indx  
   AND nam.ksppinm LIKE '%&&parameter_name%'  
 ORDER BY 1;  
 

--@getplan
set feedback off
pro 'general,outline,starts'
pro
acc type prompt 'Enter value for plan type:' default 'general'
select * from table(dbms_xplan.display) where '&&type'='general';
select * from table(dbms_xplan.display(null, null,'advanced -projection')) where '&&type'='outline';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,'ALLSTATS LAST')) where '&&type'='starts';
set feedback on
undef type
/


转载请注明本文地址



数据库中全表扫描与索引扫描的不同是?

全表扫描的意思就是要把表中所有数据过一遍才能显示数据结果,索引扫描就是索引,只需要扫描一部分数据就可以得到结果,
打个比方吧,在新华字典中,如果没有拼音或笔画索引,当我们查找“做”这个字就要从字典第一页一次往后查,一直插到Z开头的部分才能找到,即使找到也不确定后面是不是还有(假定字典是无序状态的),因此还得往后找,知道正本字典翻完,才确定“哦,原来刚才找到的那个记录就是想要的结果了”。索引扫描的意思就是我们预先知道“做”这个字在拼音的Z区域,然后根据前面目录查看"zuo"这个拼音在那一页,然后直接翻到那一页就能找到我们要的结果了,这样就能大大减少查询的时间。
 

SQL语言 怎不全表扫描直接提取最新一次的记录?

select 姓名 from 员工信息表 group by 姓名 having count(姓名) > 1

-------------------------
select * from 员工信息表
where 姓名 in (select 姓名 from 员工信息表 group by 姓名 having count(姓名) > 1)
 

www.htsjk.Com true http://www.htsjk.com/shujukunews/2583.html NewsArticle 计算cost--全表扫描,计算cost--表扫描 下面教大家如何手工算出oracle执行计划中的cost。 成本的计算方式如下: Cost = ( #SRds * sreadtim #MRds * mreadtim CPUCycles / cpuspeed ) / sreadtime #SRds - number of...
评论暂时关闭