Hakanfactor(二)

2014-11-24 08:06:48 · 作者: · 浏览: 5
,我们可以通过手工解析表SYS.TAB$的spare1字段来获取有个hakan factor的信息。下面对spare1字段内容的解释来源与网络

Lower bits (at least 12, perhaps as many as 15): H kan factor. 0×08000: MINIMIZE RECORDS_PER_BLOCK in effect0×10000: Seems to mean that the H kan factor has been fixed higher than the value calculated from non-null columns. This could be e.g. if set by event 14529 (see below) or if non-null columns have been added after a bitmap index has been created.0×20000: Table compression is enabled 综上,我们可以使用下面的过程来查看hakan factor
create or replace procedure show_hakan(
	i_table		in	varchar2,
	i_owner		in	varchar2 default user
) as
	m_obj		number(8,0);
	m_flags		varchar2(12);
	m_hakan		number(8,0);
begin
	select
		obj#, 
	to_char(
		bitand(
			spare1, to_number('ffff8000','xxxxxxxx')
		),
		'xxxxxxxx'
	)					flags,
	bitand(spare1, 32767)			hakan	-- 0x7fff	
	into
		m_obj,
		m_flags,
		m_hakan
	from
		tab$
	where	obj# in (
			select	object_id 
			from	dba_objects
			where	object_name = upper(i_table)
			and	object_type = 'TABLE'
			and	owner = upper(i_owner)
		)
	;

	dbms_output.put_line(
		'Hakan factor for object ' || 
		m_obj   || ' (' ||
		i_owner || '.' || 
		i_table || ') is ' || 
		m_hakan || ' with flags ' ||
		m_flags
	);
end;
/

drop public synonym show_hakan;
Create Public Synonym Show_Hakan For Show_Hakan;
grant execute on show_hakan to public;

Hakan factor 对位图索引的影响

我们知道位图索引是通过起始rowid和结束rowid和位图的联合作用来定位数据。因此,我们处理需要知道起始rowid和终止rowid之外,还需要知道在每个数据块中的记录数量,而这往往是很难做到的,因为每个块中存储的记录数量是不等和变化的。在这种情况下,oracle计算每个数据块中记录数量的最大值,并根据这个最大值在位图中为每个数据块分配对应数量的标识位。而计算最大值的方法受hakan factor的影响。因此,如果我们减小hakan factor,便可以控制位图中为每个数据块分配的标识位数量,从而降低位图索引的占用空间,仅一步会降低位图逻辑操作时对内存的消耗。
SQL> create table t1(c1 number); 表已创建。 SQL> insert into t1 values(1); 已创建 1 行。 SQL> / 已创建 1 行。 SQL> / 已创建 1 行。 SQL> alter table t1 minimize records_per_block; 表已更改。 SQL> create table t2 as select * from t1; 表已创建。 SQL> alter table t2 minimize records_per_block; 表已更改。 SQL> execute show_hakan('t1'); Hakan factor for object 78156 (EASY.t1) is 2 with flags 8000 PL/SQL 过程已成功完成。 SQL> execute show_hakan('t2'); Hakan factor for object 78157 (EASY.t2) is 2 with flags 8000 PL/SQL 过程已成功完成。 SQL> insert into t1 select * from t1; 已创建 3 行。 SQL> / 已创建 6 行。 SQL> / 已创建 12 行。 SQL> / 已创建 24 行。 SQL> / 已创建 48 行。 SQL> / 已创建 96 行。 SQL> / 已创建 192 行。 SQL> / 已创建 384 行。 SQL> / 已创建 768 行。 SQL> / 已创建 1536 行。 SQL> / 已创建 3072 行。 SQL> / 已创建 6144 行。 SQL> / 已创建 12288 行。 SQL> / 已创建 24576 行。 SQL> truncate table t2; 表被截断。 SQL> insert into t2 select * from t1; 已创建 49152 行。 SQL> commit; 提交完成。 select ct, count(*) from ( Select Dbms_Rowid.Rowid_Block_Number(Rowid), Count(*) Ct from t1 group by dbms_rowid.rowid_block_number(rowid) ) Group By Ct 10 order by ct 11 / CT COUNT(*) ---------- ---------- 3 16384 select ct, count(*) from ( Select Dbms_Rowid.Rowid_Block_Number(Rowid), Count(*) Ct from t2 group by dbms_rowid.rowid_block_number(rowid) ) Group By Ct 10 order by ct 11 / CT COUNT(*) ---------- ---------- 3 16384 SQL> alter table t1 nominimize records_per_block; 表已更改。 SQL> insert /*+append*/ into t1 select * from t1 where ro