選擇性(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%的適合創建索引。