Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1179580
  • 博文数量: 398
  • 博客积分: 10110
  • 博客等级: 上将
  • 技术积分: 4055
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-23 20:01
个人简介

新博客http://www.cnblogs.com/zhjh256 欢迎访问

文章分类

全部博文(398)

文章存档

2012年(1)

2011年(41)

2010年(16)

2009年(98)

2008年(142)

2007年(100)

我的朋友

分类: Oracle

2008-01-06 21:53:56

       集的势和选择性通常是在讨论查询计划时使用的两个术语。一个计划包含多个操作,其中包括一个输入的数据集和一个输出的数据集。集的势和选择性都是相对于输出结果集讨论的。

 

集的势

       在标准的PLAN_TABLE中有一列称为'Cardinality'。在上下文中,其意思是优化器估计在通过access/filter谓词后预计产生的行数。

       例如,在一个表中有2000行数据,其中有一个row列,并且数据分布到5年,那么将假设精确的统计(ALL_TAB_COLUMNS NUM_DISTINCT, LOW_VALUEHIGH_VALUE列)。当从这个表查询一年的数据时,PLAN_TABLE中的集的势(或者rows)将为400

       关键是假设精确的统计。但是有时候并不精确,在一个数据分布倾斜的情况下,直方图可能不够详细。也有在一些情况下,优化器所作的假设是无效的。

       可以使用未文档化的集的势提示:

       select /*+ CARDINALITY (t 10) */ * from table t

       该提示告诉优化器预计从t返回的行数为10行。

       更为通常的是在提示可以用在子查询中,覆盖优化器自己估计返回的行数。需要注意的是该提示的意思是在计算输出大小时忽略输入数据集的大小。

       该提示也可以使用连接集的势:

       select /*+ CARDINALITY (t1 t2 t3 100) */ {columns}

       from t1, t2, t3, t4 where ...

       如下:

SQL> create table test_card as select to_char(sysdate,'yyyy') year,t.* from all_tables t where rownum<501;

 

Table created

 

SQL> select distinct year from test_card;

 

YEAR

----

2008

 

SQL> insert into test_card select * from test_card;

 

500 rows inserted

 

SQL> insert into test_card select * from test_card;

 

1000 rows inserted

 

SQL> commit;

 

Commit complete

 

SQL> update test_card set year=year-1 where rownum<1501;

 

1500 rows updated

 

SQL> commit;

 

Commit complete

 

SQL> update test_card set year=year-1 where rownum<1001;

 

1000 rows updated

 

SQL> update test_card set year=year-1 where rownum<11;

 

10 rows updated

 

SQL> commit;

 

Commit complete

 

SQL> select count(*) from test_card group by year;

 

  COUNT(*)

----------

        10

       990

       500

       500

SQL> analyze table test_card COMPUTE STATISTICS;

 

Table analyzed

 

SQL> explain plan for

  2  select * from test_card where year='2005';

 

Explained

 

SQL> @F:\oracle\RDBMS\ADMIN\utlxpls.sql;

Cannot SET MARKUP

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 3916160364

-------------------------------------------------------------------------------

| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |           |   500 | 87500 |    15   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEST_CARD |   500 | 87500 |    15   (0)| 00:00:01 |

-------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   1 - filter("YEAR"='2005')

 

13 rows selected

      

SQL> explain plan for

  2  select /*+ CARDINALITY(t 10)*/* from test_card t where year='2005';

 

Explained

 

SQL> @F:\oracle\RDBMS\ADMIN\utlxpls.sql;

Cannot SET MARKUP

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 3916160364

-------------------------------------------------------------------------------

| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |           |    10 |  1750 |    15   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TEST_CARD |    10 |  1750 |    15   (0)| 00:00:01 |

-------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   1 - filter("YEAR"='2005')

 

13 rows selected

选择性

       选择性是指预计通过filter的行的比例,相对于一个直接数而言。如400/2000=0.20.2就是选择性。

       不同于集的势在PLAN_TABLE中没有选择性列。但是,集的势是通过选择性和将在其上操作的行的行数计算出来的。因此在选择性0.21000行输入数据集上的集的势将为200

       也有一个未文档化的选择性提示:

       select /*+SELECTIVITY (t 0.2) */ * from table t;

       该提示将会告诉优化器只有20%的数据将返回,即使没有声明where子句。

       通常在Oracle的估计不准确的情况下使用。

       不同于集的势该提示考虑输入数据集的大小,并用来计算集的势。

       但是,需要注意Metalink4121077

       ·在10g中没有选择性提示,在10g9.2中有集的势提示。

       ·可以使用未文档化的集的势提示。

阅读(3283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~