摘要:《Cardinality?》
執行計劃會顯示每一個 Statement 的步驟,每一個步驟又會顯示其 cost、cardinality,cost 顯而易見應該就是成本; cardinality 又代表什麼意思呢?
Google 翻譯是 “基數”。
http://www.oratechinfo.co.uk/cardinality.html
This is the number of rows that Oracle expects that step in the plan to evaluate.
Ask Tom 也有很實在的範例解釋。
以下是個人測試過程:
SQL> create table t as select * from dba_objects;
已建立表格.
SQL> create index t_idx on t (object_id);
已建立索引.
SQL> alter session set optimizer_mode=rule;
已更改階段作業.
Ps. Change to RBO
SQL> set autotrace traceonly
SQL> select * from t where object_id=27;
執行計畫
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T'
2 1 INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE)
Ps. Rule Base & no statistics won’t show cost and cardinality!
統計值
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
2 physical reads
0 redo size
1182 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter session set optimizer_mode=first_rows;
已更改階段作業.
Ps. Change to CBO
SQL> select * from t where object_id=27;
執行計畫
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=2 Card=491 Bytes =86907)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=491 Bytes=86907)
2 1 INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=1 Card= 196)
Ps. CBO will show cost & cardinality, but it’s not correct.
統計值
----------------------------------------------------------
262 recursive calls
0 db block gets
30 consistent gets
0 physical reads
0 redo size
1182 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> analyze table t compute statistics for all indexes for all columns;
已分析表格.
SQL> select * from t where object_id=27;
執行計畫
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=2 Card=1 Bytes=85)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=85)
2 1 INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=1 Card=1)
統計值
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
1182 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
--------------------------------------------------------------------------
結論: cardinality 指的是 oracle 估算會取得的筆數。
所以定期分析、統計資料表,將有助於執行計劃的選擇。