通过USE_CONCAT提示想到的 [转帖]_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3809 | 回复: 0   主题: 通过USE_CONCAT提示想到的 [转帖]        下一篇 
wayne
注册用户
等级:中校
经验:1690
发帖:221
精华:0
注册:2011-7-21
状态:离线
发送短消息息给wayne 加好友    发送短消息息给wayne 发消息
发表于: IP:您无权察看 2011-8-16 16:39:33 | [全部帖] [楼主帖] 楼主

在测试USE_CONCAT提示的时候遇到了一个比较奇怪的现象。

SQL> create table t as select rownum id, a.* from dba_objects a;


表已创建。

SQL> exec dbms_stats.gather_table_stats(user, 'T')


PL/SQL 过程已成功完成。

SQL> set autot trace exp
SQL> select * from t where owner = 'SYS' or OBJECT_TYPE = 'PACKAGE';
Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE (Cost=10 Card=846 Bytes=72756)
1    0   TABLE ACCESS (FULL) OF 'T' (Cost=10 Card=846 Bytes=72756)
SQL> select /*+ use_concat */ * from t
2  where owner = 'SYS' or OBJECT_TYPE = 'PACKAGE';
Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE (Cost=10 Card=846 Bytes=72756)
1    0   TABLE ACCESS (FULL) OF 'T' (Cost=10 Card=846 Bytes=72756)


在上面的测试中使用了USE_CONCAT提示,但Oracle并没有根据提示生成相应的执行计划。

下面为T建立两个索引。

SQL> create index ind_t_owner on t(owner);


索引已创建。

SQL> create index ind_t_object_type on t(object_type);


索引已创建。

SQL> select * from t where owner = 'SYS' or OBJECT_TYPE = 'PACKAGE';
Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE (Cost=10 Card=846 Bytes=72756)
1    0   TABLE ACCESS (FULL) OF 'T' (Cost=10 Card=846 Bytes=72756)
SQL> select /*+ use_concat */ * from t
2  where owner = 'SYS' or OBJECT_TYPE = 'PACKAGE';
Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE (Cost=20 Card=273 Bytes=23478)
1    0   CONCATENATION
2    1     TABLE ACCESS (FULL) OF 'T' (Cost=10 Card=31 Bytes=2666)
3    1     TABLE ACCESS (FULL) OF 'T' (Cost=10 Card=31 Bytes=2666)


建立索引后,查询的执行计划没有变。根据OWNER和OBJECT_TYPE的分布,这个结果是正常的。但是加上USE_CONCAT提示后,执行计划由一个全表扫描变为了两个全表扫描的CONCATENATION。

刚看到这个执行计划的时候,我有些迷惑,为什么开始USE_CONCAT不起作用而现在开始起作用了呢?

在建立索引以前,Oracle对T的访问路径只存在一种,即全表扫描。由于Oracle只存在一种执行计划,因此Oracle忽略了USE_CONCAT提示。当建立索引之后,Oracle存在着多种访问路径,包括对T全表扫描和对T的IND_T_OWNER索引扫描以及对T的IND_T_OBJECT_TYPE索引扫描。由于存在多种访问途径,因此优化器按照提示生成相应的计划,优化器根据提示生成执行计划的同时,对于提示中没有给出的部分,优化器会根据代价的大小来确定。而在这个查询中,全表扫描肯定比通过索引扫描代价要小,因此,优化器生成了对T表执行两次全表扫描,然后进行CONCATENATION的执行计划。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论