查看: 2261|回复: 4

一个语句优化问题

[复制链接]
认证徽章
论坛徽章:
9
ITPUB社区OCM联盟徽章
日期:2013-03-27 11:17:11奥运纪念徽章
日期:2013-06-18 09:13:52ITPUB社区千里马徽章
日期:2013-08-22 09:58:03大众
日期:2013-08-30 14:51:33路虎
日期:2013-12-01 18:25:42
发表于 2010-2-2 15:45 | 显示全部楼层 |阅读模式
执行计划如下:
pomstest@GELC> explain plan for
  2  select nvl(nvl(cp.renewal_type, cp.initial_type), pp.charge_type),
  3              nvl(cp.premium_year, pp.premium_year),
  4              nvl(cp.product_id, pp.product_id),
  5              nvl(cp.amount, pp.amount)
  6      from t_policy_product pp
  7      full join t_contract_product cp on pp.item_id = cp.item_id
  8   where (pp.item_id = :i_item_id or cp.item_id = :i_item_id);

已解释。

pomstest@GELC> set wrap off
pomstest@GELC> set linesize 1000
pomstest@GELC> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 2281297711

----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                  | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                       | 37991 |  3227K|       |  1241   (1)| 00:00:15 |
|   1 |  VIEW                          |                       | 37991 |  3227K|       |  1241   (1)| 00:00:15 |
|   2 |   UNION-ALL                    |                       |       |       |       |            |          |
|*  3 |    FILTER                      |                       |       |       |       |            |          |
|*  4 |     HASH JOIN RIGHT OUTER      |                       | 37990 |  4414K|  1752K|  1239   (1)| 00:00:15 |
|   5 |      TABLE ACCESS FULL         | T_CONTRACT_PRODUCT    | 33194 |  1361K|       |   497   (1)|
|   6 |      TABLE ACCESS FULL         | T_POLICY_PRODUCT      | 37990 |  2856K|       |   496   (2)|
|   7 |    NESTED LOOPS ANTI           |                       |     1 |    27 |       |     2   (0)| 00:00:01 |
|   8 |     TABLE ACCESS BY INDEX ROWID| T_CONTRACT_PRODUCT    |     1 |    22 |       |     2   (0)|
|*  9 |      INDEX UNIQUE SCAN         | PK_T_CONTRACT_PRODUCT |     1 |       |       |     1   (0)|
|* 10 |     INDEX UNIQUE SCAN          | PK_T_POLICY_PRODUCT   | 37990 |   185K|       |     0   (0)| 0
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("PP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID) OR "CP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID))
   4 - access("PP"."ITEM_ID"="CP"."ITEM_ID"(+))
   9 - access("CP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID))
  10 - access("PP"."ITEM_ID"="CP"."ITEM_ID")

已选择25行。

其实这里PP"."ITEM_ID"="CP"."ITEM_ID"(+)) ITEM_ID都是主键,如果我这里去掉全连接就是如下:

pomstest@GELC> explain plan for
  2  select nvl(nvl(cp.renewal_type, cp.initial_type), pp.charge_type),
  3              nvl(cp.premium_year, pp.premium_year),
  4              nvl(cp.product_id, pp.product_id),
  5              nvl(cp.amount, pp.amount)
  6      from t_policy_product pp,t_contract_product cp where  pp.item_id = cp.item_id
  7  and  (pp.item_id = :i_item_id or cp.item_id = :i_item_id);

已解释。

pomstest@GELC>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 3980163064

----------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                       |     2 |    82 |     6   (0)| 00:00:01 |
|   1 |  CONCATENATION                |                       |       |       |            |          |
|   2 |   NESTED LOOPS                |                       |     1 |    41 |     3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| T_CONTRACT_PRODUCT    |     1 |    22 |     2   (0)| 00:00:01
|*  4 |     INDEX UNIQUE SCAN         | PK_T_CONTRACT_PRODUCT |     1 |       |     1   (0)| 00:00:01 |
|   5 |    TABLE ACCESS BY INDEX ROWID| T_POLICY_PRODUCT      | 37990 |   704K|     1   (0)| 00:00:01
|*  6 |     INDEX UNIQUE SCAN         | PK_T_POLICY_PRODUCT   |     1 |       |     0   (0)| 00:00:01 |
|   7 |   NESTED LOOPS                |                       |     1 |    41 |     3   (0)| 00:00:01 |
|   8 |    TABLE ACCESS BY INDEX ROWID| T_POLICY_PRODUCT      |     1 |    19 |     2   (0)| 00:00:01
|*  9 |     INDEX UNIQUE SCAN         | PK_T_POLICY_PRODUCT   |     1 |       |     1   (0)| 00:00:01 |
|  10 |    TABLE ACCESS BY INDEX ROWID| T_CONTRACT_PRODUCT    | 33193 |   713K|     1   (0)| 00:00:01
|* 11 |     INDEX UNIQUE SCAN         | PK_T_CONTRACT_PRODUCT |     1 |       |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("CP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID))
   6 - access("PP"."ITEM_ID"="CP"."ITEM_ID")
   9 - access("PP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID))
  11 - access("PP"."ITEM_ID"="CP"."ITEM_ID")
       filter(LNNVL("CP"."ITEM_ID"=TO_NUMBER(:I_ITEM_ID)))

已选择27行。

但是这样不合乎业务逻辑啊,,外联接中如何使用已有的索引啊?
论坛徽章:
86
2015中国数据库技术大会纪念徽章
日期:2015-04-24 16:04:24马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11优秀写手
日期:2013-12-18 09:29:11日产
日期:2013-10-17 08:44:39马自达
日期:2013-08-26 16:28:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:51马上有房
日期:2014-02-19 11:55:14
发表于 2010-2-2 16:05 | 显示全部楼层
楼主修改一下用宋体吧,这个也太串了。

使用道具 举报

回复
认证徽章
论坛徽章:
9
ITPUB社区OCM联盟徽章
日期:2013-03-27 11:17:11奥运纪念徽章
日期:2013-06-18 09:13:52ITPUB社区千里马徽章
日期:2013-08-22 09:58:03大众
日期:2013-08-30 14:51:33路虎
日期:2013-12-01 18:25:42
发表于 2010-2-2 16:58 | 显示全部楼层
我的问题大概就是 为啥使用的外连接 就不使用索引了

使用道具 举报

回复
论坛徽章:
311
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
发表于 2010-2-3 00:07 | 显示全部楼层
from t_policy_product pp
  7      full join t_contract_product cp on pp.item_id = cp.item_id

相当于

from t_policy_product pp,t_contract_product cp
where pp.item_id = cp.item_id(+)

UNIOM
from t_policy_product pp,t_contract_product cp
where pp.item_id(+) = cp.item_id

这种情况下,要搜索出大部分的记录,优化器可能认为全表扫描更高效.

使用道具 举报

回复
认证徽章
论坛徽章:
9
ITPUB社区OCM联盟徽章
日期:2013-03-27 11:17:11奥运纪念徽章
日期:2013-06-18 09:13:52ITPUB社区千里马徽章
日期:2013-08-22 09:58:03大众
日期:2013-08-30 14:51:33路虎
日期:2013-12-01 18:25:42
发表于 2010-2-3 09:24 | 显示全部楼层
呵呵是的,但是你可以清楚的看到
   4 - access("PP"."ITEM_ID"="CP"."ITEM_ID"(+))
并没有做左连接

使用道具 举报

回复

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

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表