Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2885513
  • 博文数量: 599
  • 博客积分: 16398
  • 博客等级: 上将
  • 技术积分: 6875
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-30 12:04
个人简介

WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606

文章分类

全部博文(599)

文章存档

2014年(12)

2013年(56)

2012年(199)

2011年(105)

2010年(128)

2009年(99)

分类: Oracle

2010-07-08 14:01:08

在计算Cardinality的时候,ORACLE首先会利用到DENSITY。如果手工修改了NUM_DISTINCT那么DENSITY也会跟着变化。但是反过来,如果修改了DENSITY,NUM_DISTINCT就不会改变。

SQL> SELECT * FROM V$VERSION;
 
BANNER
--------------------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production
 
SQL> CREATE TABLE CARD_TEST(ID ,NAME ,VALUE) AS SELECT OBJECT_ID,OBJECT_NAME,ROUND(DBMS_RANDOM.VALUE(1,10)) FROM ALL_OBJECTS WHERE ROWNUM<=100;
 
Table created.
 
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER,'CARD_TEST',method_opt=>null);
 
PL/SQL procedure successfully completed.
 
SQL> SELECT MIN(VALUE),MAX(VALUE),COUNT(1) FROM CARD_TEST;
 
MIN(VALUE) MAX(VALUE)   COUNT(1)
---------- ---------- ----------
         1         10        100
 
SQL> COL COLUMN_NAME FORMAT A15

SQL> SELECT COLUMN_NAME,NUM_DISTINCT,DENSITY FROM USER_TAB_COL_STATISTICS WHERE TABLE_NAME='CARD_TEST';
 
COLUMN_NAME     NUM_DISTINCT    DENSITY
--------------- ------------ ----------
ID                       100        .01
NAME                     100        .01
VALUE                     10         .1
 
SQL>  EXEC DBMS_STATS.SET_COLUMN_STATS(USER,'CARD_TEST','VALUE',distcnt=>5);
 
PL/SQL procedure successfully completed.
 
SQL>  SELECT COLUMN_NAME,NUM_DISTINCT,DENSITY FROM USER_TAB_COL_STATISTICS WHERE TABLE_NAME='CARD_TEST';
 
COLUMN_NAME     NUM_DISTINCT    DENSITY
--------------- ------------ ----------
VALUE                      5         .2

可以看到,NUM_DISTINCT变化了,DENSITY也跟着变化。
此时,选择度也就是0.2,因此Cardinality=100*0.2=20
 
SQL> SET AUTOT TRACEONLY EXP
 
SQL> SELECT COUNT(1) FROM CARD_TEST WHERE VALUE=5;
Execution Plan
----------------------------------------------------------
Plan hash value: 1890630942
----------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost  |
----------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |     3 |     2 |
|   1 |  SORT AGGREGATE    |           |     1 |     3 |       |
|*  2 |   TABLE ACCESS FULL| CARD_TEST |    20 |    60 |     2 |
----------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("VALUE"=5)
Note
-----
   - cpu costing is off (consider enabling it)
 
SQL> SET AUTOT OFF

SQL> SELECT COLUMN_NAME,NUM_DISTINCT,DENSITY FROM USER_TAB_COL_STATISTICS WHERE TABLE_NAME='CARD_TEST';
 
COLUMN_NAME     NUM_DISTINCT    DENSITY
--------------- ------------ ----------
ID                       100        .01
NAME                     100        .01
VALUE                      5         .2
 
SQL> EXEC DBMS_STATS.SET_COLUMN_STATS(USER,'CARD_TEST','VALUE',DENSITY=>0.5);
 
PL/SQL procedure successfully completed.
 
SQL> SELECT COLUMN_NAME,NUM_DISTINCT,DENSITY FROM USER_TAB_COL_STATISTICS WHERE
TABLE_NAME='CARD_TEST';
 
COLUMN_NAME     NUM_DISTINCT    DENSITY
--------------- ------------ ----------
ID                       100        .01
NAME                     100        .01
VALUE                      5         .5

可以看到,DENSITY变化了,NUM_DISTINCT不会跟着变化。
此时,选择度也就是0.5,因此Cardinality=100*0.5=50

SQL> SET AUTOT TRACEONLY EXP

SQL> SELECT COUNT(1) FROM CARD_TEST WHERE VALUE=5;
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1890630942
----------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost  |
----------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |     3 |     2 |
|   1 |  SORT AGGREGATE    |           |     1 |     3 |       |
|*  2 |   TABLE ACCESS FULL| CARD_TEST |    50 |   150 |     2 |
----------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("VALUE"=5)
Note
-----
   - cpu costing is off (consider enabling it)
 
阅读(4043) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~