楼主: 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
21#
 楼主| 发表于 2009-1-8 10:53 | 只看该作者
棉花 . 但是我还是不明白我的 统计信息哪里错了. 导致使用了时间的index .

这个例子 就选择了正确的index

test@stat.r> create index IND_TAB_O on TAB (OWNER);

索引已创建。

test@stat.r> create index IND_TAB_T on TAB (LAST_DDL_TIME);

索引已创建。

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;

执行计划
----------------------------------------------------------
Plan hash value: 133653500

--------------------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |           |     1 |   177 |     3  (34)| 00:00:01 |
|*  1 |  COUNT STOPKEY                 |           |       |       |            |          |
|   2 |   VIEW                         |           |     1 |   177 |     3  (34)| 00:00:01 |
|*  3 |    SORT ORDER BY STOPKEY       |           |     1 |    97 |     3  (34)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| TAB       |     1 |    97 |     2   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | IND_TAB_O |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   3 - filter(ROWNUM<10)
   5 - access("P"."OWNER"='1')

使用道具 举报

回复
论坛徽章:
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
22#
发表于 2009-1-8 10:55 | 只看该作者
p.ownerid 的直方图收集下看看

使用道具 举报

回复
论坛徽章:
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
23#
 楼主| 发表于 2009-1-8 10:56 | 只看该作者
ownerid 这个index 我昨天已经rebuild了. 原来blevel 3 , rebuild 后 blevel 为2了. 但是还是使用change_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
24#
 楼主| 发表于 2009-1-8 11:04 | 只看该作者
原帖由 棉花糖ONE 于 2009-1-8 10:55 发表
p.ownerid 的直方图收集下看看


开始有直方图, 不起作用,我就给删除掉了.刚才我有添加上也不起作用.

现在就差charge_time 上index rebuild 了.

使用道具 举报

回复
招聘 : 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
25#
发表于 2009-1-8 11:19 | 只看该作者
原帖由 oradbHome 于 2009-1-8 10:53 发表
棉花 . 但是我还是不明白我的 统计信息哪里错了. 导致使用了时间的index .

这个例子 就选择了正确的index

test@stat.r> create index IND_TAB_O on TAB (OWNER);

索引已创建。

test@stat.r> create index IND_TAB_T on TAB (LAST_DDL_TIME);

索引已创建。

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;

执行计划
----------------------------------------------------------
Plan hash value: 133653500

--------------------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |           |     1 |   177 |     3  (34)| 00:00:01 |
|*  1 |  COUNT STOPKEY                 |           |       |       |            |          |
|   2 |   VIEW                         |           |     1 |   177 |     3  (34)| 00:00:01 |
|*  3 |    SORT ORDER BY STOPKEY       |           |     1 |    97 |     3  (34)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| TAB       |     1 |    97 |     2   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | IND_TAB_O |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM




1、alter table TAB modify (last_ddl_time not null)
2、将owner='1' 改成owner='SYS'

使用道具 举报

回复
论坛徽章:
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
26#
 楼主| 发表于 2009-1-8 11:31 | 只看该作者
原帖由 anlinew 于 2009-1-8 11:19 发表




1、alter table TAB modify (last_ddl_time not null)
2、将owner='1' 改成owner='SYS'

使用了last_ddl_time 的index .

test@stat.r>
test@stat.r> SELECT * FROM (
  2   SELECT *
  3     FROM TAB p
  4    WHERE p.owner='SYS'
  5    ORDER BY p.last_ddl_time
  6   ) WHERE ROWNUM < 10;

执行计划
----------------------------------------------------------
Plan hash value: 3461240345

-------------------------------------------------------------------------------------------
| Id  | Operation                     | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |           |     9 |  1593 |     4   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                |           |       |       |            |          |
|   2 |   VIEW                        |           |     9 |  1593 |     4   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS BY INDEX ROWID| TAB       | 23349 |  2211K|     4   (0)| 00:00:01 |
|   4 |     INDEX FULL SCAN           | IND_TAB_T |    20 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   3 - filter("P"."OWNER"='SYS')

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

使用道具 举报

回复
论坛徽章:
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
27#
 楼主| 发表于 2009-1-8 11:33 | 只看该作者
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
28#
发表于 2009-1-8 11:35 | 只看该作者
hint使其使用owner上的索引,对比一致读

使用道具 举报

回复
论坛徽章:
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
29#
 楼主| 发表于 2009-1-8 11:46 | 只看该作者
原帖由 anlinew 于 2009-1-8 11:35 发表
hint使其使用owner上的索引,对比一致读


一致读 差了很多.
owner='SYS'  记录很多.没有选择index 是正确的

test@stat.r> SELECT * FROM (
  2  SELECT /*+ INDEX(P IND_TAB_O)*/ *
  3    FROM TAB p
  4   WHERE p.owner='SYS'
  5   ORDER BY p.last_ddl_time
  6  ) WHERE ROWNUM < 10;

已选择9行。


执行计划
----------------------------------------------------------
Plan hash value: 133653500

----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |           |     9 |  1593 |       |  1250   (1)| 00:00:16 |
|*  1 |  COUNT STOPKEY                 |           |       |       |       |            |          |
|   2 |   VIEW                         |           | 23349 |  4035K|       |  1250   (1)| 00:00:16 |
|*  3 |    SORT ORDER BY STOPKEY       |           | 23349 |  2211K|  5944K|  1250   (1)| 00:00:16 |
|   4 |     TABLE ACCESS BY INDEX ROWID| TAB       | 23349 |  2211K|       |   729   (1)| 00:00:09 |
|*  5 |      INDEX RANGE SCAN          | IND_TAB_O | 23349 |       |       |    56   (2)| 00:00:01 |
----------------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   3 - filter(ROWNUM<10)
   5 - access("P"."OWNER"='SYS')


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        646  consistent gets
          0  physical reads
          0  redo size
       1294  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          9  rows processed


test@stat.r> SELECT * FROM (
  2  SELECT  *
  3    FROM TAB p
  4   WHERE p.owner='SYS'
  5   ORDER BY p.last_ddl_time
  6  ) WHERE ROWNUM < 10;

已选择9行。


执行计划
----------------------------------------------------------
Plan hash value: 3461240345

-------------------------------------------------------------------------------------------
| Id  | Operation                     | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |           |     9 |  1593 |     4   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                |           |       |       |            |          |
|   2 |   VIEW                        |           |     9 |  1593 |     4   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS BY INDEX ROWID| TAB       | 23349 |  2211K|     4   (0)| 00:00:01 |
|   4 |     INDEX FULL SCAN           | IND_TAB_T |    20 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   3 - filter("P"."OWNER"='SYS')


统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
       1308  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          9  rows processed

[ 本帖最后由 oradbHome 于 2009-1-8 11:53 编辑 ]

使用道具 举报

回复
招聘 : 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
30#
发表于 2009-1-8 11:55 | 只看该作者
对于含rownum <n 这样条件的查询来说
真实的执行成本除了与数据逻辑分布情况有关,还与数据的物理分布情况有很大关系

比如再插入相同数量的数据

insert into test select '1' OWNER,  OBJECT_NAME  ,  SUBOBJECT_NAME,  OBJECT_ID,
  DATA_OBJECT_ID,  OBJECT_TYPE,  CREATED,  LAST_DDL_TIME ,  TIMESTAMP,
  STATUS,  TEMPORARY,  GENERATED,  SECONDARY
  from test where owner='SYS'
之后再对比:

SELECT * FROM (
    SELECT *
      FROM TAB p
     WHERE p.owner='1'
     ORDER BY p.last_ddl_time
    ) WHERE ROWNUM < 10;
与owner='SYS'时的一致读

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

使用道具 举报

回复

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

本版积分规则 发表回复

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