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次
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;