楼主: yangtingkun

[笔记] oracle的执行计划居然出错!

[复制链接]
论坛徽章:
5
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33蓝色妖姬
日期:2006-04-12 22:10:01会员2006贡献徽章
日期:2006-04-17 13:46:34
21#
发表于 2004-11-28 17:41 | 只看该作者
让oracle 自行进行类型变换不是个好习惯.
没看清你贴子,不好意思

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
22#
 楼主| 发表于 2004-11-30 10:25 | 只看该作者

ft,问题居然重现了。

重建之后是没有问题的。

现在估计是快速刷新导致的这个问题。

使用道具 举报

回复
论坛徽章:
168
马上加薪
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:10:582012新春纪念徽章
日期:2012-01-04 11:49:54蜘蛛蛋
日期:2011-12-05 16:08:56ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41设计板块每日发贴之星
日期:2011-07-22 01:01:02ITPUB官方微博粉丝徽章
日期:2011-06-30 12:30:16管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:33
23#
发表于 2004-11-30 10:45 | 只看该作者

Re: ft,问题居然重现了。

最初由 yangtingkun 发布
[B]重建之后是没有问题的。

现在估计是快速刷新导致的这个问题。 [/B]


bug?
oracle support怎么说?

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
24#
 楼主| 发表于 2004-11-30 11:16 | 只看该作者
还没有找oracle的support。

发现无论是否重建,基于rule的查询结构都是正确的。
如果使用analyze分析,for all indexed columns或for all columns可以使查询得到正确的结果。
如果使用dbms_stats.gather_table_stats,无论method_opt指定for all indexed columns或for all columns都无法使查询得到正确的结果。

使用道具 举报

回复
论坛徽章:
2
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34
25#
发表于 2004-11-30 11:33 | 只看该作者
找找oracle的support然後把結果跟大家分享一下

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
26#
 楼主| 发表于 2004-12-3 21:15 | 只看该作者
终于找到错误原因了。

居然是因为初始化参数query_rewrite_enabled的值是TRUE

一直没有注意这个参数,是因为的建立物化视图复制的时候并没有指定ENABLE QUERY REWRITE子句,在PLT_PLAT表上也没有建立其它物化视图,而且初始化参数query_rewrite_integrity的值是enforced,这是最严格的设置,没有想到在这种情况下oracle仍然使用了query rewrite,而且查询重写后得到的结果也不正确。
这样看来oracle的查询重写、统计信息的收集以及CBO执行策略还是有些问题的。

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
27#
 楼主| 发表于 2004-12-3 21:16 | 只看该作者
下面简要描述一下不同情况下会出现什么问题。
1.将查询重写关闭,无论是否有统计信息,也无论统计信息生成的方式,查询都不会出错。
SQL> alter session set query_rewrite_enabled = false;
Session altered.
SQL> set autot on exp
SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;
149 rows selected.
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=84 Bytes=14028)
   1    0   HASH JOIN (Cost=11 Card=84 Bytes=14028)
   2    1     HASH JOIN (Cost=7 Card=84 Bytes=10752)
   3    2       TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=84 Bytes=5376)
   4    2       TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=334 Bytes=21376)
   5    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=334 Bytes=13026)
SQL> analyze table plt_plat delete statistics;
Table analyzed.
SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;
149 rows selected.
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   2    1     NESTED LOOPS
   3    2       NESTED LOOPS
   4    3         TABLE ACCESS (FULL) OF 'PLT_PLAT'
   5    3         TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   6    5           INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)
   7    2       INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
28#
 楼主| 发表于 2004-12-3 21:18 | 只看该作者
2.打开查询重写,基于rule的查询结果正确,如果没有统计信息,all_rows和first_rows结果都是错误的。


SQL> alter session set query_rewrite_enabled = true;


Session altered.


SQL> analyze table plt_plat delete statistics;


Table analyzed.


SQL> alter session set optimizer_mode = rule;


Session altered.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


149 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=RULE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   2    1     NESTED LOOPS
   3    2       NESTED LOOPS
   4    3         TABLE ACCESS (FULL) OF 'PLT_PLAT'
   5    3         TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   6    5           INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)
   7    2       INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)



SQL> alter session set optimizer_mode = first_rows;


Session altered.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=29 Card=13 Bytes=2132)
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT' (Cost=2 Card=1 Bytes=72)
   2    1     NESTED LOOPS (Cost=29 Card=13 Bytes=2132)
   3    2       TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=13 Bytes=1196)
   4    2       INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE) (Cost=1 Card=1)



SQL> alter session set optimizer_mode = all_rows;


Session altered.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=13 Bytes=2132)
   1    0   HASH JOIN (Cost=7 Card=13 Bytes=2132)
   2    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=13 Bytes=1196)
   3    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=1307 Bytes=94104)

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
29#
 楼主| 发表于 2004-12-3 21:19 | 只看该作者
3.打开查询重写,只有使用带FOR ALL (INDEXED) COLUMNS子句的ANALYZE TABLE去收集统计信息,CBO的结果才是正确的,使用其他方式收集统计信息,CBO的查询结果都是错误的。


SQL> analyze table plt_plat delete statistics;


Table analyzed.


SQL> alter session set optimizer_mode = choose;


Session altered.


SQL> analyze table plt_plat compute statistics;


Table analyzed.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=155 Bytes=20460)
   1    0   HASH JOIN (Cost=7 Card=155 Bytes=20460)
   2    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=84 Bytes=6048)
   3    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=334 Bytes=20040)



SQL> analyze table plt_plat delete statistics;


Table analyzed.


SQL> exec dbms_stats.gather_table_stats(user, 'PLT_PLAT', method_opt => 'FOR ALL COLUMNS');


PL/SQL procedure successfully completed.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


no rows selected


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=84 Bytes=11928)
   1    0   HASH JOIN (Cost=7 Card=84 Bytes=11928)
   2    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=151 Bytes=11778)
   3    1     TABLE ACCESS (FULL) OF 'PLT_PLAT' (Cost=3 Card=334 Bytes=21376)





SQL> exec dbms_stats.delete_table_stats(user, 'PLT_PLAT');


PL/SQL procedure successfully completed.


SQL> analyze table plt_plat compute statistics for all columns;


Table analyzed.


SQL> select pp.id, pp.plat_name, pp.plat_class, city.id, city.plat_name, city.plat_class
  2  ,province.id,province.plat_name,province.plat_class
  3  from plt_plat pp,
  4  plt_plat city,
  5  plt_plat province
  6  where pp.plat_father=city.id
  7  and city.plat_father=province.id
  8  and pp.plat_class=4
  9  ;


149 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   2    1     NESTED LOOPS
   3    2       NESTED LOOPS
   4    3         TABLE ACCESS (FULL) OF 'PLT_PLAT'
   5    3         TABLE ACCESS (BY INDEX ROWID) OF 'PLT_PLAT'
   6    5           INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)
   7    2       INDEX (RANGE SCAN) OF 'IND_PLT_PLAT_PLAT_FATHER' (NON-UNIQUE)

使用道具 举报

回复
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
30#
 楼主| 发表于 2004-12-3 21:22 | 只看该作者
这里有完整的记录
http://blog.itpub.net/post/468/7086

使用道具 举报

回复

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

本版积分规则 发表回复

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