9 rows selected
SQL语句中没有where条件,选取的count(*)也没有直接object_id关系。但是执行计划中出现了索引对象,最重要的是执行计划从原来的294下降到48。
观察这个执行计划,路径中出现了Index Fast Full Scan动作,而且没有回表动作。Oracle选择这样的路径思路是这样的:object_id是索引列,所有object_id的取值均在叶子节点上。关键难点在于空置null,Oracle中null值不会进入单键值索引对象叶子节点。这也就是为什么Oracle在object_id不设置为not null时不走索引路径的原因。
Oracle在取巧!在CBO时代,对索引路径的选择是一个非常出巧的地方。RBO时代,十五种等级规则,实际就意味着十五种路径方式。我们看RBO时代,有没有这样的策略。
SQL> explain plan for select /*+rule*/count(*) from t;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2966233522
-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | TABLE ACCESS FULL| T |
-----------------------------------
Note
-----
- rule based optimizer used (consider using cbo)
13 rows selected
从上面情况看,RBO时代没有这样的“取巧”过程。
约束not null和null带给我们的不仅仅是数据约束的保证,从这个例子上,可以看到not null还可以带来一些高效的执行计划,实现性能上的提升。
3、主键列的Group By
单纯使用Group By是没有意义的,一般都是伴随着如count、sum等聚合函数方法。另外一个关于Group By的特性是:空值null也会被进行Group By。
主键Primary Key的特性是唯一和非空,如果对其进行Group By,每个对象的操作数量就是1。这个过程其实也是不需要进行真正操作的。
下面我们进行测试。
SQL> explain plan for select empno, count(*) from scott.emp group by empno;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------
Plan hash value: 1749432681
-----------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 56 | 1 (0)| 00:00:01 |
| 1 | SORT GROUP BY NOSORT| | 14 | 56 | 1 (0)| 00:00:01 |
| 2 | INDEX FULL SCAN | PK_EMP | 14 | 56 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------