一: 基数(Cardinality) 列唯一键(Distinct_keys)的数量,比如性别,该列只有男女之分,所以这一列基数是2。主键列的基数等于行数。
select count(*) from emp; 总行数
select count(distinct empno) from emp; 基数
基数越高 说明 这个列 重复数据 很少
选择性
选择性 = 基数 / 总行数 * 100%
当某个列的选择性大于20%,就可以在这个列随便建立索引。
作业1 写个脚本
1 .抓出列选择性大于20%的列。
2. 这个列没有建立索引。
3. 这个列出现在where当中。
二: 直方图
这个表示进行了动态采样。
收集统计信息脚本
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns size 1', --------------------
no_invalidate => FALSE,
degree => 1,
cascade => TRUE);
END;
/
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns size 1', --------------------
no_invalidate => FALSE,
degree => 1,
cascade => TRUE);
END;
/
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
查看统计信息,如果不收集统计信息,那么这个命令就是空的
select a.column_name,
b.num_rows,
a.num_distinct Cardinality,
round(a.num_distinct / b.num_rows * 100, 2) selectivity,
a.histogram,
a.num_buckets
from dba_tab_col_statistics a, dba_tables b
where a.owner = b.owner
and a.table_name = b.table_name
and a.owner = 'SCOTT'
and a.table_name = 'TEST';
b.num_rows,
a.num_distinct Cardinality,
round(a.num_distinct / b.num_rows * 100, 2) selectivity,
a.histogram,
a.num_buckets
from dba_tab_col_statistics a, dba_tables b
where a.owner = b.owner
and a.table_name = b.table_name
and a.owner = 'SCOTT'
and a.table_name = 'TEST';
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
如果没有对列收集统计信息(没收集直方图),那么ocb就因为所有列分布都是均衡的。
1. 直方图应该对基数低的进行收集。 2. 直方图应该对where条件后面的列收集。
换种方式收集统计信息:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns size skewonly', ------------
no_invalidate => FALSE,
degree => 1,
cascade => TRUE);
END;
/
---------------------------------收集直方图后会把数据分布存在数据字典里面,也就是直方图的桶里面。
题目二:
1. 检查这个列基数很低。
2. 列出现在where条件里面。
3. 没有收集直方图。
题目三:
1. 检查基数很高。
2. 没有出现在where条件里面。
3. 收集了直方图。
------------------------------------------------------------------------------------------------------------------------------------------------
三: 集群因子
select object_id,
rowid,
dbms_rowid.rowid_relative_fno(rowid) file#,
dbms_rowid.rowid_block_number(rowid) block#,
dbms_rowid.rowid_row_number(rowid) row#
from test
order by object_id;
rowid,
dbms_rowid.rowid_relative_fno(rowid) file#,
dbms_rowid.rowid_block_number(rowid) block#,
dbms_rowid.rowid_row_number(rowid) row#
from test
order by object_id;
集群因子越接近总块数,就说明这列在表里面排过序。
集群因子表示索引回表的物理io扫描次数
减少集群因子,但不实用
create table test as select * from test order by object_id;
select index_name,clustering_factor from user_indexes;
题目三: 写sql手动将这个集群因子算出来
两个sql版本,一个plsql