首页 > 数据库 > Oracle > cbo心得(选择率,基数,直方图)(四)
1, 存在表和索引上的统计信息,存在直方图
为了更明显的说明直方图的作用,我修改一下上面的创建的表,进一步的增加列ID的倾斜性。
[@more@]SQL> drop table sunwg purge;
表已删除。
SQL> create table sunwg (id number);
表已创建。
SQL> create index ind_sunwg on sunwg(id);
索引已创建。
SQL> insert into sunwg select 1 from dba_objects where rownum < 4000;
已创建3999行。
SQL> insert into sunwg select rownum from dba_objects where rownum < 2002;
已创建4001行。
SQL> commit;
在表SUNWG中ID = 1的记录一共有4000条,占了全部记录的66%。
分析表和索引,并且统计直方图信息。
SQL> analyze table sunwg compute statistics for table for all indexes for column
s id size 10;
表已分析。
还是执行前面的那两个SQL看看有了直方图信息之后的效果。
SQL> select * from sunwg where id = 50;
执行计划
----------------------------------------------------------
Plan hash value: 3109917279
---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 3 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IND_SUNWG | 1 | 3 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=50)
因为ID = 50的记录在表SUNWG中仅有一条,所以才用索引范围扫描的效率会更好一些。CBO选择了高效的执行方式。
SQL> select * from sunwg where id = 1;
执行计划
----------------------------------------------------------
Plan hash value: 650063079
---------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
---------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 3600 | 10800 | 5 (0)|
|* 1 | INDEX FAST FULL SCAN| IND_SUNWG | 3600 | 10800 | 5 (0)| 00:00:01
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=1)
在ID = 1的时候,CBO选择了执行快速索引全扫描。ORACLE意识到了ID = 1的时候结果集的变化,所以CBO没有采用索引范围扫描,而是选择了更加高效的快速索引全扫描。
结合前面的例子,我们可以知道对于那些严重倾斜的列来说,直方图信息是多么的重要。所以我们在收集统计信息的时候,一定不要忽略了直方图这个重要的因素。下面是存在直方图信息时,其他谓词的情况:
Where 条件 | Oracle估计记录数 | 表中实际记录数 | Oracle估算公式(猜想) |
ID = 1 | 3600 | 4000 | |
ID > 1 | 2400 | 2000 | |
ID >= 1 | 6000 | 6000 | |
ID = 110 | 1 | 0 | 1<= X<= 6000 * DENSITY |
ID + 1 > 1 | 300 | 6000 | 6000* 5% |
ID + 1 >= 1 | 300 | 6000 | 6000* 5% |
ID + 1 > 1 AND ID + 1 > 1 | 300 | 6000 | 6000* 5% |
ID > 1 AND ID < 50 | 147 | 48 | |
ID >= 1 AND ID <= 50 | 3747 | 4049 |
这次ORACLE估算公式一栏很多都是空着的。因为在存在直方图信息的时候,计算Rows的算法特别的复杂。我下面会详细的介绍一下这部分内容。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8394333/viewspace-1000433/ ,如需转载,请注明出处,否则将追究法律责任。