楼主: oradbHome

性能调整 order by 和 rownum 导致执行计划改变.附录10053

[复制链接]
论坛徽章:
97
ITPUB元老
日期:2008-06-30 12:48:39暖羊羊
日期:2015-03-04 14:50:372015年新春福章
日期:2015-03-06 11:57:312010数据库技术大会纪念徽章
日期:2015-04-23 10:33:192011数据库大会纪念章
日期:2015-04-23 10:33:192012数据库大会纪念章
日期:2015-04-23 10:33:192013数据库大会纪念章
日期:2015-04-23 10:33:192014数据库大会纪念章
日期:2015-04-23 10:33:19林肯
日期:2013-10-31 12:31:382013年新春福章
日期:2013-02-25 14:51:24
31#
 楼主| 发表于 2009-1-8 13:18 | 只看该作者
原帖由 anlinew 于 2009-1-8 11:55 发表
对于含rownum  


插入owner=1的数据后.
test@stat.r> SELECT * FROM (
  2  SELECT  *
  3    FROM TAB p
  4   WHERE p.owner='1'
  5   ORDER BY p.last_ddl_time
  6  ) WHERE ROWNUM < 10;

采用默认采用owner列的index .
的逻辑读取 367  consistent gets

但是我analyze 后 . 就采用last_ddl_time列的index . 逻辑读取变为6. 和owner='SYS'的逻辑读基本一致.

我也同意rownum 的实际的数据物理存储有关系.

使用道具 举报

回复
论坛徽章:
97
ITPUB元老
日期:2008-06-30 12:48:39暖羊羊
日期:2015-03-04 14:50:372015年新春福章
日期:2015-03-06 11:57:312010数据库技术大会纪念徽章
日期:2015-04-23 10:33:192011数据库大会纪念章
日期:2015-04-23 10:33:192012数据库大会纪念章
日期:2015-04-23 10:33:192013数据库大会纪念章
日期:2015-04-23 10:33:192014数据库大会纪念章
日期:2015-04-23 10:33:19林肯
日期:2013-10-31 12:31:382013年新春福章
日期:2013-02-25 14:51:24
32#
 楼主| 发表于 2009-1-8 13:27 | 只看该作者

回复 #30 anlinew 的帖子

insert into tab select '1' OWNER,  OBJECT_NAME  ,  SUBOBJECT_NAME,  OBJECT_ID,
  DATA_OBJECT_ID,  OBJECT_TYPE,  CREATED,  LAST_DDL_TIME ,  TIMESTAMP,
  STATUS,  TEMPORARY,  GENERATED,  SECONDARY
  from tab where owner='SYS'

这样批量插入数据后owner=1的数据在物理上是在一起的. 所以使用LAST_DDL_TIME上index 返回结果很快.

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
33#
发表于 2009-1-8 13:34 | 只看该作者
11:52:41 SQL> select * from (select * from test where owner='1' order by created) where rownum <10;

已选择9行。

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=9 Bytes=159
          3)

   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=5 Card=10 Bytes=1770)
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (TABLE) (Cost=
          5 Card=7015 Bytes=596275)

   4    3         INDEX (FULL SCAN) OF 'I_TEST_3' (INDEX) (Cost=2 Card
          =42)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        107  consistent gets
          0  physical reads
          0  redo size
       1405  bytes sent via SQL*Net to client
        504  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          9  rows processed

11:52:48 SQL> select * from (select * from test where owner='SYS' order by created) where rownum <10;

已选择9行。


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=9 Bytes=159
          3)

   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=5 Card=9 Bytes=1593)
   3    2       TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (TABLE) (Cost=
          5 Card=6916 Bytes=587860)

   4    3         INDEX (FULL SCAN) OF 'I_TEST_3' (INDEX) (Cost=2 Card
          =38)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
       1403  bytes sent via SQL*Net to client
        504  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          9  rows processed


我这个例子更明显一些,一样的数据,一样的执行计划,很不一样的执行成本

[ 本帖最后由 anlinew 于 2009-1-8 13:38 编辑 ]

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
34#
发表于 2009-1-8 13:39 | 只看该作者
原帖由 oradbHome 于 2009-1-8 13:27 发表
insert into tab select '1' OWNER,  OBJECT_NAME  ,  SUBOBJECT_NAME,  OBJECT_ID,
  DATA_OBJECT_ID,  OBJECT_TYPE,  CREATED,  LAST_DDL_TIME ,  TIMESTAMP,
  STATUS,  TEMPORARY,  GENERATED,  SECONDARY
  from tab where owner='SYS'

这样批量插入数据后owner=1的数据在物理上是在一起的. 所以使用LAST_DDL_TIME上index 返回结果很快.

这个不是主要的,看上面的例子,是更慢

使用道具 举报

回复
论坛徽章:
97
ITPUB元老
日期:2008-06-30 12:48:39暖羊羊
日期:2015-03-04 14:50:372015年新春福章
日期:2015-03-06 11:57:312010数据库技术大会纪念徽章
日期:2015-04-23 10:33:192011数据库大会纪念章
日期:2015-04-23 10:33:192012数据库大会纪念章
日期:2015-04-23 10:33:192013数据库大会纪念章
日期:2015-04-23 10:33:192014数据库大会纪念章
日期:2015-04-23 10:33:19林肯
日期:2013-10-31 12:31:382013年新春福章
日期:2013-02-25 14:51:24
35#
 楼主| 发表于 2009-1-8 14:29 | 只看该作者
原帖由 anlinew 于 2009-1-8 13:34 发表
11:52:41 SQL> select * from (select * from test where owner='1' order by created) where rownum  select * from (select * from test where owner='SYS' order by created) where rownum  


select * from (select * from test where owner='1' order by created) where rownum <10;

执行多次试一试.?
我第一次是 104  consistent gets , 第二次就变为 6 consistent gets .

使用道具 举报

回复
招聘 : Java研发
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
36#
发表于 2009-1-8 17:18 | 只看该作者
原帖由 oradbHome 于 2009-1-8 14:29 发表


select * from (select * from test where owner='1' order by created) where rownum  

那个例子的确会有偏差
这样构造的数据可能更符合我要表达的意思
[php]
insert into test select '1' OWNER,  OBJECT_NAME  ,  SUBOBJECT_NAME,  OBJECT_ID,
  DATA_OBJECT_ID,  OBJECT_TYPE, sysdate CREATED, sysdate  LAST_DDL_TIME ,  TIMESTAMP,
  STATUS,  TEMPORARY,  GENERATED,  SECONDARY
  from test where owner='SYS'
[/php]

你好好想想stopkey下数据的访问机制,应该就明白我的意思了

而实际情况下可能业务就是这个情况,要查的数据通常就是近期发生的数据

使用道具 举报

回复
论坛徽章:
97
ITPUB元老
日期:2008-06-30 12:48:39暖羊羊
日期:2015-03-04 14:50:372015年新春福章
日期:2015-03-06 11:57:312010数据库技术大会纪念徽章
日期:2015-04-23 10:33:192011数据库大会纪念章
日期:2015-04-23 10:33:192012数据库大会纪念章
日期:2015-04-23 10:33:192013数据库大会纪念章
日期:2015-04-23 10:33:192014数据库大会纪念章
日期:2015-04-23 10:33:19林肯
日期:2013-10-31 12:31:382013年新春福章
日期:2013-02-25 14:51:24
37#
 楼主| 发表于 2009-1-9 09:34 | 只看该作者

回复 #36 anlinew 的帖子

谢谢. 我在仔细研究下.

使用道具 举报

回复
论坛徽章:
138
19周年集字徽章-19
日期:2020-06-08 08:30:56马上加薪
日期: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马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02路虎
日期:2013-11-22 12:26:18问答徽章
日期:2014-05-08 12:15:31
38#
发表于 2009-1-9 09:51 | 只看该作者
最好的方法就是建组合索引,这样不管你where字段的选择性高不高,只要走组合索引都能快

使用道具 举报

回复

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

本版积分规则 发表回复

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