计算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 |

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

--以下是@脚本

[email protected]

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;

[email protected]

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;

[email protected]

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;

[email protected]

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;

[email protected]_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;

[email protected]

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

/

转载请注明本文地址

计算cost--全表扫描

时间: 2024-11-06 04:35:40

计算cost--全表扫描的相关文章

为什么全表扫描成本(COST)公式里面要除以sreadtim

全表扫描的成本计算公式 如下: Cost = ( #SRds * sreadtim + #MRds * mreadtim + CPUCycles / cpuspeed ) / sreadtim 全表扫描的时候,单块读次数=0,#SRds表示单块读次数.全表扫描的成本里面,CPU消耗其实非常少,可以忽略不计,所以全表扫描的公式可以改写为: Cost = #MRds * mreadtim / sreadtim #MRds 表示多块读io次数 mreadtim 表示一次多块读耗费时间 sreadtim

SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析

原文:SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析 在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index Seek))呢?是否所有情况都是如此?又该如何优化呢? 下面我们通过一些简单的例子来分析理解这些现象.下面的实验环境为SQL SERVER 2008,如果在不同版本有所区别,欢迎指正. 堆表单索引 首先我们构建我们测试需要实验环境,

oracle在组合索引上,只使用部分列进行查询(查询时必须包含前导列,否则会走全表扫描)

实验环境:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production 1.创建表插入数据 SQL> create table txtx(id int,name char(2),tx char(3),id1 int,primary key(id,name,tx)); 表已创建. SQL> insert into txtx values(1,'tx','tx',1); 已创建 1 行. SQL> i

执行计划-数据访问方式(全表扫描与4种索引的方式)

执行计划 Oracle执行计划的相关概念: Rowid:系统给oracle数据的每行附加的一个伪列,包含数据表名称,数据库id,存储数据库id以及一个流水号等信息,rowid在行的生命周期内唯一. Recursive sql:为了执行用户语句,系统附加执行的额外操作语句,譬如对数据字典的维护等. Row source(行源):oracle执行步骤过程中,由上一个操作返回的符合条件的行的集合. Predicate(谓词):where后的限制条件. Driving table(驱动表):又称为连接的

表访问方式----&gt;全表扫描(Full Table Scans, FTS)

全表扫描(Full Table Scans, FTS) 全表扫描是指Oracle在访问目标表里的数据时,会从该表所占用的第一个区(EXTENT)的第一个块(BLOCK)开始扫描,一直扫描到该表的高水位线(HWM,High Water Mark),Oracle会对这期间读到的所有数据施加目标SQL的where条件中指定的过滤条件,最后只返回那些满足过滤条件的数据. 不是说全表扫描不好,事实上Oracle在做全表扫描操作时会使用多块读,ORACLE采用一次读入多个数据块 (database bloc

怎么对10亿数据量级的mongoDB作高效的全表扫描

转自:http://quentinxxz.iteye.com/blog/2149440 一.正常情况下,不应该有这种需求 首先,大家应该有个概念,标题中的这个问题,在大多情况下是一个伪命题,不应该被提出来.要知道,对于一般较大数据量的数据库,全表查询,这种操作一般情况下是不应该出现的,在做正常查询的时候,如果是范围查询,你至少应该要加上limit. 说一下,我的应用场景:用于全量建立搜索引擎的索引.这就是一种需要用到全表扫描的非一般情况.对于全表扫描的结果,我们没有排序要求. 二.情况说明 既然

Oracle 表的访问方式(1) ---全表扫描、通过ROWID访问表

1.Oracle访问表的方式 全表扫描.通过ROWID访问表.索引扫描 2.全表扫描(Full Table Scans, FTS) 为实现全表扫描,Oracle顺序地访问表中每条记录,并检查每一条记录是否满足WHERE语句的限制条件.ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描,而不是只读取一个数据块,这极大的减少了I/O总次数,提高了系统的吞吐量,所以利用多块读的方法可以十分高效地实现全表扫描.需要注意的是只有在全表扫描的情况下才能使用多块读操作.在这种

如何导致全表扫描原因

转一位大神的笔记. 导致表的执行计划做全表扫描的原因: u       SQL谓词列没有建相应的索引 u       谓词列建有相应的索引,但执行计划没有使用 Oracle不使用b*tree索引的情况大致如下 1:where条件中和null比较可能导致不使用索引 2:count,sum,ave,max,min等聚集操作时可能导致不使用索引 3:显示或者隐式的函数转换导致不使用索引 4:在cbo模式下,统计信息过于陈旧导致不使用索引 5:组合索引中没有使用前导列导致没有使用索引 6:访问的数据量超

mongodb与mysql全表扫描能力PK

nosql的数据在内存里,而传统rdbms,某个select第一次执行的时候,如果发现内存里没有需要的数据(比如mysql的innodb buffer pool),会去从磁盘读取,然后再开始计算,这样子从原理上就必然比nosql要慢一些,但是,会慢多少呢?可以用一个分组统计的全表扫描来PK下. 测试环境如下: server:阿里云服务器(Ubuntu14.04+1核cpu和 1G内存) mysql:5.5.41 mysql服务端参数:innodb_buffer_pool_size = 512M 

oracle全表扫描166G的表只花了6分钟

如何最大限制利用cpu?如何最快速的扫描完大表.如果大表有主键,count(*)就会走主键,oracle只需要扫描主键就能完成. 假设这个表没有主键,那么count(*)的时候只能走全表扫描,数据就非常慢.这里用full(a)强制走全表来模拟. --找100G以上的分区表 SQL> @getsegsize_big Enter value for tablespace_name: Enter value for owner: Enter value for how_big_m: 100000 OW