很简单的执行计划看不太明白,请大家指点一下

[复制链接]
查看11 | 回复9 | 2008-2-13 12:43:03 | 显示全部楼层 |阅读模式
SELECT * FROM t WHERE val1 = 11 AND val2 = 11;
------------------------------------------------
| Id | Operation | Name |
------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | TABLE ACCESS BY INDEX ROWID| T |
|* 2 | INDEX RANGE SCAN | T_VAL2_I |
------------------------------------------------
1 - filter("VAL1"=11)
2 - access("VAL2"=11)

2 - access("VAL2"=11)已经走了索引,为什么还会有1 - filter("VAL1"=11)的过滤呢?
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
INDEX RANGE SCAN,说明val2 = 11的记录多于1条,且它们val1不都是11。所以需要进一步过滤。
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
原帖由 过过招 于 2009-12-2 13:37 发表
INDEX RANGE SCAN,说明val2 = 11的记录多于1条,且它们val1不都是11。所以需要进一步过滤。


我没有说清楚,我的 意思是都已经决定走索引T_VAL2_I ,就是说这个时候OACLE直接到索引中找出相关的数据的ROWID直接访问好了,为什么还要有过滤? 过滤式在什么时候发生的?
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
那地方过滤不是显示了table access by rowid吗,val1不在索引里,所以通过val2=1后得到符合条件的记录,再回表得到val1,然后得到val1=1的记录
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
恩,继续这个话题,请问为什么2个字段(id ,id 2)都有index的话
无论and 条件怎么写都会走id 的索引。也就是先过滤id,再过滤id2?

SQL> select * from a whereid =8 and id2=8;
IDID2
---------- ----------
8
8

执行计划
----------------------------------------------------------
Plan hash value: 3632291705
-------------------------------------------------------------------------------------
| Id| Operation
| Name| Rows| Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
| | 1 |26 | 2 (0)| 00:00:01 |
|*1 |TABLE ACCESS BY INDEX ROWID| A | 1 |26 | 2 (0)| 00:00:01 |
|*2 | INDEX RANGE SCAN
| A_IDX | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID2"=8)
2 - access("ID"=8)

SQL>select * from a where id2=8 and id=8;
IDID2
---------- ----------
8
8

执行计划
----------------------------------------------------------
Plan hash value: 3632291705
-------------------------------------------------------------------------
| Id| Operation
| Name| Rows| Bytes | Cost (%CPU)
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT
| | 1 |26 | 2 (0)
|*1 |TABLE ACCESS BY INDEX ROWID| A | 1 |26 | 2 (0)
|*2 | INDEX RANGE SCAN
| A_IDX | 1 | | 1 (0)
-------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID2"=8)
2 - access("ID"=8)
[ 本帖最后由 lixiang114 于 2009-12-2 14:48 编辑 ]
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
如果你不想回表做filter,只要index也包含val2这列就行了。
SQL> create table t(val1 number,val2 number);
Table created.
SQL> create indexT_VAL2_I on t(val1,val2);
Index created.

SQL> alter table t add(val3 number);
Table altered.
SQL> SELECT * FROM t WHERE val1 = 11 AND val2 = 11;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 161426604
------------------------------------------------
| Id| Operation
| Name |
------------------------------------------------
| 0 | SELECT STATEMENT
|
|
| 1 |TABLE ACCESS BY INDEX ROWID| T|
|*2 | INDEX RANGE SCAN
| T_VAL2_I |
------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("VAL1"=11 AND "VAL2"=11)

[ 本帖最后由 viadeazhu 于 2009-12-2 14:53 编辑 ]
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
都有索引是啥意思??,是2个单列索引吗
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
CBO认为走id上的索引cost更低而已。
交换where conditions的做法不会有什么作用,CBO也不会这么笨的。
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
是的,两个单列索引
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
原帖由 viadeazhu 于 2009-12-2 14:50 发表
如果你不想回表做filter,只要index也包含val2这列就行了。
SQL> create table t(val1 number,val2 number);
Table created.
SQL> create indexT_VAL2_I on t(val1,val2);
Index created.

SQL> alter table t add(val3 number);
Table altered.
SQL> SELECT * FROM t WHERE val1 = 11 AND val2 = 11;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 161426604
------------------------------------------------
| Id| Operation
| Name |
------------------------------------------------
| 0 | SELECT STATEMENT
|
|
| 1 |TABLE ACCESS BY INDEX ROWID| T|
|*2 | INDEX RANGE SCAN
| T_VAL2_I |
------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("VAL1"=11 AND "VAL2"=11)


什么事回表?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行