SELECTIVITY 选择率讨论

选择性(SELECTIVITY)这个是个老话题了,做优化的DBA肯定听过。

在说这个选择率之前需要澄清几个概念:

基数(CARDINALITY)

某个列唯一键(Distinct_Keys)的数量叫作基数。主键列的基数等于表的总行数。基数的高低影响列的数据分布。

以测试表test为例,owner列和object_id列的基数分别如下所示。

select count(distinct owner),count(distinct object_id),count(*) from test;
 COUNT(DISTINCT OWNER) COUNT(DISTINCT OBJECT_ID)   COUNT(*)
-------------------- ------------------------ ----------
                  29                    72462      72462

我们可以看到 object_id 列基数比较高,所以它的数据分布比较均匀,

选择性(SELECTIVITY)

基数与总行数的比值再乘以100%就是某个列的选择性。

SELECTIVITY = CARDINALITY/total_rows *100%  也就是 选择率 = 基数/表总行数 *100%

现在来构造数据测试一下:

create table test as select * from dba_objects;

--收集 SYS.TEST统计信息,不然 ‘dba_tab_col_statistics’会没有SYS.TABLE的统计信息。
BEGIN
   DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SYS',
                                 tabname          => 'TEST',
                                 estimate_percent => 100,
                                 method_opt => 'for all columns size 1',
                                 no_invalidate    => FALSE,
                                 degree           => 1,
                                 cascade          => TRUE);
 END;
 /


--刷新数据库信息,避免干扰。也可以不做
begin
   dbms_stats.flush_database_monitoring_info;
  end;
 /


--查看SYS.TEST 各个列的选择率
select a.table_name,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 = 'SYS'
    and a.table_name = 'TEST';

查看 ‘selectivity’列 >20%的适合创建索引。

猜你喜欢

转载自my.oschina.net/u/3862440/blog/2874013
今日推荐