Oracle:集群因子
什么是集群因子(Clustering Factor)呢?集群因子是通过一个索引扫描一张表时需要访问的表的数据块的数量。
集群因子的计算方法如下:
(1) 扫描一个索引;
(2) 比较某行的ROWID和前一行的ROWID,如果这两个ROWID不属于同一个数据块,那么集群因子增加1;
(3) 整个索引扫描完毕后,就得到了该索引的集群因子。
以上面集群因子的计算方式可以看出,集群因子反映了索引范围扫描可能带来的对整个表访问过程的IO开销情况,如果集群因子接近于表存储的块数,说明这张表是按照索引字段的顺序存储的。如果集群因子接近于行的数量,那说明这张表不是按索引字段顺序存储的。在计算索引访问成本时,集群因子十分有用。集群因子乘以选择性参数就是访问索引的开销。(是优化器决定是否用索引的关键因素)
官方说明:
----row存储的越有序,clustering factor的值越低
----当clustering factor很高时,说明index entry (rowid) 是 随机指向一些block的,在一个大的index range scan时,这样为了读取这些rowid指向的block,就需要一次又一次重复的去读这些block。
----当clustering factor值低时,说明index keys (rowid) 是指向的记录是存储在相同的block里,这样去读row时,只需要在同一个block里读取就可以了,这样减少重复读取blocks的次数
Index Clustering Factor说明
简单的说,Index Clustering Factor是通过一个索引扫描一张表,需要访问的表的数据块的数量,即对I/O的影响,也代表索引键存储位置是否有序。
(1)、如果越有序,即相邻的键值存储在相同的block,那么这时候Clustering Factor的值就越低;
(2)、如果不是很有序,即键值是随机的存储在block上,这样在读取键值时,可能就需要一次又一次的去访问相同的block,从而增加了I/O。
Clustering Factor的计算方式如下:
(1)、扫描一个索引(large index range scan);
(2)、比较某行的rowid和前一行的rowid,如果这两个rowid不属于同一个数据块,那么cluster factor增加1;
(3)、整个索引扫描完毕后,就得到了该索引的clustering factor。
如果clustering factor接近于表存储的块数,说明这张表是按照索引字段的顺序存储的。
如果clustering factor接近于行的数量,那说明这张表不是按索引字段顺序存储的。
在计算索引访问成本的时候,这个值十分有用。Clustering Factor乘以选择性参数(selectivity)就是访问索引的开销。
如果这个统计数据不能真实反映出索引的真实情况,那么可能会造成优化器错误的选择执行计划。另外如果某张表上的大多数访问是按照某个索引做索引扫描,那么将该表的数据按照索引字段的顺序重新组织,可以提高该表的访问性能。
测试
产生问题
----查看一下数据库的版本----
SQL> select * from v$version where rownum=1;BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production----创建一张测试表jack----
SQL> create table jack as select * from dba_objects where 1=2;Table created.----将数据无序的插入jack表中----
SQL> begin2 for i in 1..10 loop3 insert /*+ append */ into jack select * from dba_objects order by i;4 commit;5 end loop;6 end;7 /PL/SQL procedure successfully completed.SQL> select count(*) from jack;COUNT(*)
----------725460----查看一下表的大小-----
SQL> set wrap off
SQL> col owner for a10;
SQL> col segment_name for a15;
SQL> select segment_name,blocks,extents,bytes/1024/1024||'M' "size" from user_segments where segment_name='JACK';SEGMENT_NAME BLOCKS EXTENTS size
------------- ---------- ---------- --------
JACK 11264 82 88M----在object_id上创建索引----
SQL> create index jack_ind on jack(object_id);Index created.----查看一下索引的大小----
SQL> select segment_name,segment_type,blocks,extents,bytes/1024/1024||'M' "size" from user_segments where segment_name='JACK_IND';SEGMENT_NAME SEGMENT_TYPE BLOCKS EXTENTS size
------------ ------------------ ---------- ---------- ---------
JACK_IND INDEX 1664 28 13M----在没有收集相关的统计信息之前,查看一下index clustering factor----
SQL> select index_name,clustering_factor,num_rows from user_indexes where index_name='JACK_IND';INDEX_NAME CLUSTERING_FACTOR NUM_ROWS
--------------- ----------------- ----------
JACK_IND 725460 725460----简单的收集一下统计信息----
SQL> exec dbms_stats.gather_table_stats(user,'jack',cascade=>true);PL/SQL procedure successfully completed.----再次查看index clustering factor----
SQL> select index_name,clustering_factor,num_rows from user_indexes where index_name='JACK_IND';INDEX_NAME CLUSTERING_FACTOR NUM_ROWS
-------------- ----------------- ----------
JACK_IND 725460 725460 ----显然统计信息收集前和后,clustering factor值不变,说在创建索引的时候,会收集表中的数据真正的行数。并且这里的clustering factor等num_rows,也说明表的clustering factor是无序的。----查看一个确定值,然后查看执行计划----
SQL> explain plan for select * from jack where object_id=1501;Explained.SQL> select * from table(dbms_xplan.display);PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2860868395--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 970 | 13 (0)| 00
| 1 | TABLE ACCESS BY INDEX ROWID| JACK | 10 | 970 | 13 (0)| 00
|* 2 | INDEX RANGE SCAN | JACK_IND | 10 | | 3 (0)| 00
--------------------------------------------------------------------------------Predicate Information (identified by operation id):PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------2 - access("OBJECT_ID"=1501)14 rows selected. ----在这里走了索引,cost为13.SQL> alter system flush buffer_cache;System altered.SQL> set autotrace traceonly;----查询一个范围的执行计划----
SQL> select * from jack where object_id>1000 and object_id<2000;9880 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 949574992--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9657 | 914K| 1824 (1)| 00:00:22 |
|* 1 | TABLE ACCESS FULL| JACK | 9657 | 914K| 1824 (1)| 00:00:22 |
--------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------1 - filter("OBJECT_ID"<2000 AND "OBJECT_ID">1000)Statistics
----------------------------------------------------------0 recursive calls0 db block gets10993 consistent gets10340 physical reads0 redo size471945 bytes sent via SQL*Net to client7657 bytes received via SQL*Net from client660 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)9880 rows processed ----注意,object_id上是有索引的,但是这里并没有使用索引,而是使用了全表扫描。SQL> alter system flush buffer_cache;System altered.----强制走索引,查看执行计划----
SQL> select /*+ index(jack jack_ind) */ * from jack where object_id>1000 and object_id<2000;9880 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 2860868395----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9657 | 914K| 9683 (1)| 00:01:57 |
| 1 | TABLE ACCESS BY INDEX ROWID| JACK | 9657 | 914K| 9683 (1)| 00:01:57 |
|* 2 | INDEX RANGE SCAN | JACK_IND | 9657 | | 24 (0)| 00:00:01 |
----------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - access("OBJECT_ID">1000 AND "OBJECT_ID"<2000)Statistics
----------------------------------------------------------0 recursive calls0 db block gets10561 consistent gets164 physical reads0 redo size988947 bytes sent via SQL*Net to client7657 bytes received via SQL*Net from client660 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)9880 rows processed
----强制走索引之后,使用了index range scan,但是cost变成了9683,而全表扫描时是1824.
----还有比较一下两次查询中物理读的情况:全表扫描的物理读明显比索引的要高很多,但是Oracle却没有使用索引。
----因此Oracle认为走索引的Cost比走全表扫描大,而是大N倍,CBO是基于Cost来决定执行计划的。
----由此得出,对于索引的Cost,Oracle是根据clustering factor参数来计算的,而该实验中的clustering factor参数是很高的,数据存储无序。这就造成了Oracle认为走索引的cost比全表扫描的大。
解决问题:
|
小结
通过以上说明和测试,可以看到clustering factor也是索引健康的一个重要判断的标准。其值越低越好。它会影响CBO选择正确的执行计划。但是注意一点,clustering factor总是趋势与不断恶化的。
转载于:https://blog.51cto.com/newcourage/1942656
Oracle:集群因子相关推荐
- linux+Oracle集群课程全面升级
作为国内最早从事开源架构师级课程研发的公司,从2006年10月开始,荣新稳步提升,将互联网运维作为主导就业方向,并将Linux集群架构课程发展成为国内最顶级.覆盖技术最全面的Linux课程,作为荣新I ...
- was连接oracle rac集群,Oracle集群(RAC)及 jdbc 联接双机数据库
oracle集群url配置 oracle集群中plsql和java程序连接方式非集群中plsql连接配置: www.2cto.com DB1_193 = (DESCRIPTION = (ADDRESS ...
- 【Oracle 集群】Linux下Oracle RAC集群搭建之基本测试与使用(九)
Oracle 11G RAC数据库安装(九) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总 ...
- 2.oracle的安装常识,Oralce服务器,oracle集群,oracle服务介绍,用户解锁相关
1 oracle的安装常识(oracle10g和oracle11g的版本差别): A 安装目录都不要有中文和空格 B oracle10g支持winxp 不支持win7,8和vista;Oracl ...
- linux下安装oracle集群,【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)...
目录 数据库安装 继oracle集群安装之后,接下来也是最重要的数据库安装,整个数据库安装难度不大,用户以oracle用户身份登录RAC1主节点,对解压后的文件安装.主节点下安装后,其他所有结点自动安 ...
- mac node oracle,将Python3.5(Mac OS X El Capitan)连接到Oracle集群(远程)
我正在尝试将Python3.5(Mac OS X El Capitan)连接到Oracle集群(远程). 对于安装cx_Oracle,我设置了: export ORACLE_HOME=/Applica ...
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
集群概念介绍(一)) 白宁超 2015年7月16日 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习 ...
- ORACLE集群日志收集,【RAC】Oracle RAC集群环境下日志文件结构
在Oracle RAC环境中,对集群中的日志的定期检查是必不可少的.通过查看集群日志,可以早期定位集群环境中出现的问题,以便将问题消灭在萌芽状态.简单介绍一下有关Oracle集群环境中日志的结构,方便 ...
- oracle数据库集群采用的是形式,铁道部采用Oracle集群数据库进行TMIS系统“三级建库”...
综述 铁道部利用Oracle9i集群数据库系统(Oracle9i RAC),顺利开展铁道部运输管理信息系统(TMIS)的"三级建库"工程--在各铁路局和铁路分局利用Oracle9i ...
最新文章
- 移动端web开发常见问题
- 基于pygame的贪吃蛇游戏
- centos6.5安装配置zabbix3.0.3
- 谷歌浏览器安卓版_谷歌Chrome Canary 82安卓版现可复制图片到剪贴板
- 前端面试题汇总(jQuery)
- flex皮肤制作---通过flash
- 学习Google Chrome源码
- “斗”转星移,高精度(NTP网络授时)北斗授时系统
- 声音信号处理基频检测和时频分析
- 如何测算信息化项目软件运维费?
- unity球体添加光源_Unity 3D光源-Point Light点光源详解/灯泡、模拟灯光效果教程
- 国产系统为什么用linux,为什么国产操作系统不用Unix,而是集体用Linux
- Unity WebGL 发布内存优化
- H3C交换机常用配置
- fluxion-wifi破解/钓鱼
- VRP和调度问题的主流精确算法和启发式算法
- 【动态规划】什么是动态规划
- web前端svg图标使用(关于阿里iconfont的symbol 引用)
- sketch的切图技巧总结:如何批量切出固定大小的切图并保留透明部分?
- 下载到的电子书格式是epub,这种格式如何打开?
热门文章
- php声明一个类的关键字,php中怎么实例化一个类
- .gitignore文件_Django项目.gitignore文件建议忽略文件清单及是否需要忽略数据库迁移文件...
- 2018-2019-2 20175224 实验五《网络编程与安全》实验报告
- 怎么查看一个网站是用什么语言编写的?
- EasyUI实现工地领款单项目
- CentOS中无法使用setup命令 -bash:setup: command not found
- extjs--combox用法
- 关于[一个基于WF的业务流程平台]表设计的说明
- 栈中函数调用原理_详解
- Android—Navigation的使用