1.集群因子的算法:
通过dbms_rowid.rowid_block_number(rowid)找到记录对应的block 号。索引中记录了rowid,因此oracle 就可以根据索引中的rowid来判断记录是否是在同一个block 中。举个例子,比如说索引中有a,b,c,d,e五个记录,首先比较a,b 是否在同一个block,如果不在同一个block 那么Clustering Factor +1,然后继续比较b,c 同理,如果b,c 不在同一个block,那么Clustering Factor+1,这样一直进行下去,直到比较了所有的记录。根据算法我们就可以知道clustering factor 的值介于block 数和表行数之间。如果clustering factor 接近block 数,说明表的存储和索引存储排序接近,也就是说表中的记录很有序,这样在做index range scan 的时候能,读取少量的data block 就能得到我们想要的数据,代价比较小。如果clustering factor 接近表记录数,说明表的存储和索引排序差异很大,在做index range scan 的时候,会额外读取多个block,因为表记录分散,代价较高。
 
2.什么是rowid?

SQL> select rowid from t;

ROWID
------------------
AAASEzAAEAAAAFFAAA

SQL> select length(rowid) from t;

LENGTH(ROWID)
-------------
18

rowid一共18位

最前面6位表示data object number

之后后3位表示datafile number

之后后6位表示datablock number

最后面3位表示row number

3.如何根据rowid查询出来相应的块号等信息?

SQL> select
2 rowid,
3 dbms_rowid.rowid_relative_fno(rowid) rel_fno,--返回rowid对应的文件号
4 dbms_rowid.rowid_block_number(rowid) blockno,--返回rowid所在的块号
5 dbms_rowid.rowid_row_number(rowid) rowno--返回该行数据在block中的相对位置
6 from t where rownum=1;

ROWID             REL_FNO  BLOCKNO   ROWNO
------------------------  ------------- ------------- -------
AAASEzAAEAAAAFFAAA      4      325      0

4.能改集群因子吗?重建索引会改变集群因子吗?

不会,索引是根据创建时列的值排序创建的,只能create table .. order by 索引列,才能改变集群因子。

5.集群因子是如何影响性能的?

假设一个表有1千万行,只需要返回1w行数据,走索引。

select * from t where rowid<=10000;

走索引要先返回10000个rowid,回表要回10000次

select * from test where rowid=xxxx
 
假设10000个rowid在10个块中,那么回表时,物理回表只有10次
耗时10*10ms
假设10000个rowid在10000个块中,那么回表时,物理回表只有10000次
耗时100000*10ms
 
6.什么情况下集群因子不影响性能?
1.不回表
2.表都在buffer cache中
3.返回数据少,主键扫描或走唯一索引就跟集群因子没有关系
 
7.集群因子影响那个索引扫描?
index range scan 
index full scan
index skip scan
index fast full scan跟rowid没有关系,所以集群因子不影响
 
8.反转建索引会导致集群因子的增加。

SQL> create table test as select * from dba_objects;

表已创建。

SQL> create index objid on test(object_id);

索引已创建。

SQL> select index_name,clustering_factor from user_indexes where table_name='TEST';

INDEX_NAME CLUSTERING_FACTOR
------------------------------------------------------------ -----------------
OBJID 1085

SQL> select count(distinct dbms_rowid.rowid_block_number(rowid))from test;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
1027

SQL> select count(*) from test;

COUNT(*)
----------
72063

反转建立索引

SQL> alter index objid rebuild reverse;

索引已更改。

SQL> select index_name,clustering_factor from user_indexes where table_name='TEST';

INDEX_NAME CLUSTERING_FACTOR
------------------------------------------------------------ -----------------
OBJID 72061

SQL> select count(*) from test;

COUNT(*)
----------
72063

SQL> select count(distinct dbms_rowid.rowid_block_number(rowid))from test;

COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
1027

9.sql实现集群因子的算法

WITH T AS
(SELECT OWNER COLUMN_NAME,
LEAD(OWNER, 1, OWNER) OVER(ORDER BY OWNER) NEXT_COLUMN_NAME,
ROWID ROWID_NUM,
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCK_ID,
LEAD(ROWID) OVER(ORDER BY OWNER) NEXT_ROWID_NUM,
LEAD(DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID),
1,
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)) OVER(ORDER BY OWNER) NEXT_BLOCK_ID
FROM TEST A
WHERE OWNER IS NOT NULL
ORDER BY OWNER)
SELECT COUNT(*) 记录数,COUNT(DISTINCT BLOCK_ID) BLOCK_ID_SUM,
SUM(CASE
WHEN T.BLOCK_ID = T.NEXT_BLOCK_ID THEN
0
ELSE
1
END) + 1 集群因子,
SUM(CASE
WHEN T.COLUMN_NAME = T.NEXT_COLUMN_NAME AND
T.BLOCK_ID <> T.NEXT_BLOCK_ID THEN
1
ELSE
0
END) 值同_块不同
FROM T;

 
 
 

Oracle学习----集群因子(Clustering Factor)的更多相关文章

  1. 集群因子(Clustering Factor)

    clustering factor是CBO使用的统计信息,用来衡量一个表中的列是否是规则排序存放的. 在通过索引访问表的时候,被用来作为代价评估的指示器.扫描索引的时候,clustering fact ...

  2. Oracle Index Clustering Factor(集群因子)

    一.本文说明: 今天在做测试的时候发现字段上有索引,但是执行计划就是不走索引,经过在网上查找才发现原来是索引的集群因子过高导致的.本文属于转载 二.官网说明 The index clustering ...

  3. 【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)

    Oracle 11G RAC数据库安装(八) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总 ...

  4. Clustering Factor——索引的成本指标

    使用索引是我们面对海量数据搜索是一种常用的手段.通过有效的索引访问,可以使我们更快的访问到需要的数据,减少物理.逻辑IO,从而提高系统性能.在CBO时代,Oracle对于提交SQL的执行路径是有所选择 ...

  5. 【转】【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)

    原文地址:http://www.cnblogs.com/baiboy/p/orc8.html   阅读目录 目录 数据库安装 参考文献 相关文章 Oracle 11G RAC数据库安装(八) 概述:写 ...

  6. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  7. Oracle学习线路

    出自huyangg的博客,地址是:oracle学习路线图 1.sql.pl/sql(网上有很多的视频,可以做一个简单的入手,然后看几本书,多做实验)    作为oracle的基本功,需要大家对sql和 ...

  8. Oracle学习指南

    Oracle学习指南 你走的那天,我决定不落泪,迎着风撑着眼帘用力不眨眼 创建数据库.创建用户.创建表空间.创建表.插入数据..... 1.用系统用户登录,任选系统用户 代码: >>sql ...

  9. Oracle rac集群环境中的特殊问题

    备注:本文摘抄于张晓明<大话Oracle RAC:集群 高可用性 备份与恢复> 因为集群环境需要多个计算机协同工作,要达到理想状态,必须要考虑在集群环境下面临的新挑战. 1.并发控制 在集 ...

随机推荐

  1. front-end

    http://info.1688.com/detail/1139720782.html http://segmentfault.com/q/1010000000136513 http://h5apps ...

  2. SQL中EXISTS和IN用法

    SQL中EXISTS的用法  指定一个子查询,检测行的存在. 语法:EXISTS subquery 参数:subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INT ...

  3. php 文件上传 以及保存在本地的乱码问题处理

    要知道两点: ①浏览器传到PHP程序中是UTF-8编码 ②PHP程序保存上传的文件,要转换成GBK编码才保存在本地中,否则如果直接使用浏览器传过来的文件名保存在本地,会出现文件名乱码. <?ph ...

  4. mysql 连接url中useUnicode=true&characterEncoding=UTF-8 的作用

    添加的作用是:指定字符的编码.解码格式.            例如:mysql数据库用的是gbk编码,而项目数据库用的是utf-8编码.这时候如果添加了useUnicode=true&cha ...

  5. ANDROID_MARS学习笔记_S04_007_从服务器获取微博数据时间线

    一.代码 1.xml(1)activity_main.xml <?xml version="1.0" encoding="utf-8"?> < ...

  6. USB数据线上的“疙瘩”:原来有这么大用处!

    在不少键盘.鼠标或是游戏外设的数据线末端我们都能见到一小段金属圆环.虽然这算得上是习以为常的一个设计,但如果说到其具体作用的话很多人一下子还真回答不上来.反正笔者在这里先可以告诉大家,这货肯定不是简简 ...

  7. 如何设置SVN提交时强制添加注释

    windows版本: 1.新建一个名为pre-commit.bat的文件并将该文件放在创建的库文件的hooks文件夹中 2.pre-commit.bat文件的内容如下: @echo off set S ...

  8. Web三维技术:Flash Builder+away3d平台搭建(含演示视频)

    转自:http://www.cnblogs.com/beer/archive/2011/07/08/2101492.html 前言:作为页面中实验设备的显示层,需要一个swf作为显示的UI.虽然可以用 ...

  9. HDOJ --- 1159 Common Subsequence

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  10. HDU-1339 A Simple Task

    http://acm.hdu.edu.cn/showproblem.php?pid=1339 正常做法超时,要有点小技巧存在. A Simple Task Time Limit: 2000/1000 ...