您好,欢迎访问一九零五行业门户网

Oracle约束Constraint对于CBO优化器的作用

进入cbo优化器时代之后,成本计算值决定执行计划的选取已经成为主流。一条性能良好的执行计划建立在尽可能ldquo;贴切rdquo;的统
进入cbo优化器时代之后,成本计算值决定执行计划的选取已经成为主流。一条性能良好的执行计划建立在尽可能“贴切”的统计量基础上。cbo内部又经历了两个时代——io cost和cpu cost,两者的区别就在于系统统计量(system statistical)的应用。
rbo时代,执行计划其实也是有评估的。rbo的执行计划评定级别不会像cbo成本粒度那么细,而是15个路径等级评定。等级编号低的执行计划比等级编号高的执行计划更会被选择到。
在这个过程中,我们其实还是忽略了影响执行计划的因素,就是约束(constraint)。constraint对于数据库对象很重要,所谓约束,就是建立在数据表、数据列上的规则限制。constraint的存在目的就是将业务规则融入到数据表设计中。
constraint确定描述了数据表的一些固有特性,比如非空、外键,就从一个程度上给出了数据表特性的描述。经常性的将constraint作为一种数据完整性约束的实现,但是对于cbo而言,约束也是搜寻“捷径”执行计划的重要信息来源。从经验上看,约束能够给cbo带来的高效执行计划作用,是不可忽视的。
本篇介绍几个常见的业务场景,说明在合理规划约束的情况下,cbo能够生成更好地执行计划。
--------------------------------------分割线 --------------------------------------
相关阅读:
oracle完整性约束
oracle的约束和索引
从oracle的约束到索引
oracle常用数据类型和完整性约束
ora-02291: 违反完整约束条件 …… - 未找到父项关键字
--------------------------------------分割线 --------------------------------------
1、执行环境介绍
我们同时要使用cbo和rbo进行测试过程,选择oracle 11g进行测试。
sql> select * from v$version;
banner
---------------------------------
oracle database 11g enterprise edition release 11.2.0.3.0 - production
pl/sql release 11.2.0.3.0 - production
core 11.2.0.3.0 production
tns for linux: version 11.2.0.3.0 - production
nlsrtl version 11.2.0.3.0 – production
当前默认使用cbo优化器组件。
sql> show parameter optimizer
name                                type        value
------------------------------------ ----------- ------------------------------
optimizer_mode                      string      all_rows
optimizer_use_sql_plan_baselines    boolean    true
(篇幅原因,有省略……)
2、“null还是not null”大不一样
我们在实际设计数据库中,经常会忽略字段非空设置。不少朋友和开发团队对于这个细节不以为然,认为这个设置就是会影响到插入过程。一些朋友认为:在应用层面验证一下就可以了。但是实际上,,null与not null,大不一样!有很多方面的差异和问题,纯应用层面验证是不能解决问题的。
笔者从性能优化器角度,介绍一下忽视not null效果的问题。我们首先创建实验数据表t。
--数据表t
sql> create table t as select * from dba_objects;
table created
--其他用途索引
sql> create index idx_t_id on t(object_id);
index created
--统计量收集
sql> exec dbms_stats.gather_table_stats(user,'t',cascade => true);
pl/sql procedure successfully completed
还是我们经常设置的场景,就是没有where条件的count动作。
sql> explain plan for select count(*) from t;
explained
sql> select * from table(dbms_xplan.display);
plan_table_output
-----------------------------------------------------
plan hash value: 2966233522
-------------------------------------------------
| id  | operation          | name | rows  | cost (%cpu)| time    |
-------------------------------------------------
|  0 | select statement  |      |    1 |  294  (1)| 00:00:04 |
|  1 |  sort aggregate    |      |    1 |            |          |
|  2 |  table access full| t    | 75609 |  294  (1)| 00:00:04 |
----------------------------------------------
9 rows selected
很正常的执行计划,因为需要检索所有的数据行记录,检索数据表所有的记录是比较直观的想法。这个fts执行计划成本值294。我们修改一下索引列object_id的属性,将其从原先的null设置为not null。
sql> alter table t modify object_id not null;
table altered
sql> explain plan for select count(*) from t;
explained
sql> select * from table(dbms_xplan.display);
plan_table_output
--------------------------------------------------------------------------------
plan hash value: 3570898368
--------------------------------------------------------------------------
| id  | operation            | name    | rows  | cost (%cpu)| time    |
--------------------------------------------------------------------------
|  0 | select statement      |          |    1 |    48  (3)| 00:00:01 |
|  1 |  sort aggregate      |          |    1 |            |          |
|  2 |  index fast full scan| idx_t_id | 75609 |    48  (3)| 00:00:01 |
--------------------------------------------------------------------------
9 rows selected
其它类似信息

推荐信息