查看: 4199|回复: 13

first_rows模式下sql 优化

[复制链接]
论坛徽章:
12
复活蛋
日期:2012-11-19 08:22:46妮可·罗宾
日期:2016-10-12 10:02:44沸羊羊
日期:2015-02-12 09:39:42马上有车
日期:2015-01-06 13:31:22马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08比亚迪
日期:2013-12-24 15:48:09三菱
日期:2013-11-01 18:13:00劳斯莱斯
日期:2013-08-21 10:11:54红旗
日期:2013-08-02 10:40:25
跳转到指定楼层
1#
发表于 2012-4-23 17:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
With the Partitioning and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production

SQL> col type for a10
SQL> show parameter optimizer_mode

NAME                                 TYPE       VALUE
------------------------------------ ---------- ------------------------------
optimizer_mode                       string     FIRST_ROWS

SQL> create table test_a as  select * from dba_objects;

Table created.

SQL> insert into test_a select * from dba_objects;

153134 rows created.

SQL> /

153134 rows created.

SQL> /

153134 rows created.

SQL> /

153134 rows created.

SQL> /

153134 rows created.

SQL> commit;

Commit complete.

SQL> select count(*) from test_a     ;

  COUNT(*)
----------
    918804

SQL> create index IDX_A on TEST_A (OBJECT_ID);

Index created.

SQL> create index IDX_B on TEST_A (CREATED);

Index created.
SQL>create index IDX_C on TEST_A (OBJECT_ID, CREATED);
Index created.
SQL> set autot traceonly
SQL> select *
  2    from test_a t
  3   where t.object_id = 800
  4     and t.created >= to_date('2005-9-7 ', 'yyyy-mm-dd')
  5     and t.created <= to_date('2005-10-7 ', 'yyyy-mm-dd')
  6   order by t.created;

6 rows selected.


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=7 Card=4 Bytes=7
          08)

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'TEST_A' (Cost=7 Card=4 B
          ytes=708)

   2    1     INDEX (RANGE SCAN) OF 'IDX_B' (NON-UNIQUE) (Cost=3 Card=
          799)





Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4300  consistent gets
        109  physical reads
          0  redo size
       1464  bytes sent via SQL*Net to client
        655  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          6  rows processed

生产库有很多这样的order by 语句,也不可避免,
这个执行计划走IDX_B
idx_a的选择性很高,直方图已经收集。
这样的语句生产库上很多。该怎么优化呢?




招聘 : 数据库管理员
论坛徽章:
11
授权会员
日期:2009-06-17 21:55:31马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02劳斯莱斯
日期:2014-01-16 21:09:18复活蛋
日期:2012-11-21 19:44:35ITPUB 11周年纪念徽章
日期:2012-10-09 18:07:31ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26ITPUB元老
日期:2010-08-09 11:32:43生肖徽章2007版:虎
日期:2009-11-24 18:46:412009日食纪念
日期:2009-07-22 09:30:00
2#
发表于 2012-4-23 19:30 | 只看该作者
SESSION级别设置 _sort_elimination_cost_ratio = 5 测试下

不过,还是应该多测试下,把optimizer_mode改回CHOOSE

使用道具 举报

回复
论坛徽章:
12
复活蛋
日期:2012-11-19 08:22:46妮可·罗宾
日期:2016-10-12 10:02:44沸羊羊
日期:2015-02-12 09:39:42马上有车
日期:2015-01-06 13:31:22马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08比亚迪
日期:2013-12-24 15:48:09三菱
日期:2013-11-01 18:13:00劳斯莱斯
日期:2013-08-21 10:11:54红旗
日期:2013-08-02 10:40:25
3#
 楼主| 发表于 2012-4-23 22:45 | 只看该作者
westzq1984 发表于 2012-4-23 19:30
SESSION级别设置 _sort_elimination_cost_ratio = 5 测试下

不过,还是应该多测试下,把optimizer_mode改 ...

_sort_elimination_cost_ratio = 5 可走对。
生产系统optimizer_mode不能改。

使用道具 举报

回复
论坛徽章:
3
优秀写手
日期:2014-03-04 06:00:13马上有对象
日期:2014-03-25 09:37:36秀才
日期:2015-09-14 10:08:30
4#
发表于 2012-4-23 23:43 | 只看该作者
没有分析过,期待高人解析。

使用道具 举报

回复
论坛徽章:
71
ITPUB元老
日期:2007-07-19 08:57:15茶鸡蛋
日期:2013-04-19 13:54:28迷宫蛋
日期:2013-04-24 13:52:552014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:112014年世界杯参赛球队:喀麦隆
日期:2014-05-20 16:06:36沸羊羊
日期:2015-02-12 09:15:56乌索普
日期:2016-06-24 14:29:162013年新春福章
日期:2013-02-25 14:51:24蛋疼蛋
日期:2013-02-19 14:05:00
5#
发表于 2012-4-24 00:00 | 只看该作者
create index IDX_C on TEST_A (CREATED,OBJECT_ID);  把created 放前面!

使用道具 举报

回复
求职 : 数据库管理员
论坛徽章:
10
ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292014年新春福章
日期:2014-02-18 16:44:08优秀写手
日期:2013-12-27 06:00:12ITPUB社区千里马徽章
日期:2013-06-09 10:15:342013年新春福章
日期:2013-02-25 14:51:24奥运纪念徽章
日期:2012-11-28 09:33:31奥运纪念徽章
日期:2012-11-20 10:27:31ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42马上有对象
日期:2014-02-18 16:44:08
6#
发表于 2012-4-24 00:40 | 只看该作者
oralce 9I下默认cbo认为排序是非常消耗内存的,默认应该是最高,所以你后面的order by create,oracle会选择使用create上的索引,来避免排序,也就很自然的选择了index_b了,_sort_elimination_cost_ratio隐含参数默认为0,也就是排序成本无限大,而这个值在9I cbo下会直接影响执行计划,而_sort_elimination_cost_ratio是用来衡量排序与不排序的成本百分比的,当不排序成本/排序成本>_sort_elimination_cost_ratio 执行计划走排序反之则不走排序

使用道具 举报

回复
论坛徽章:
12
复活蛋
日期:2012-11-19 08:22:46妮可·罗宾
日期:2016-10-12 10:02:44沸羊羊
日期:2015-02-12 09:39:42马上有车
日期:2015-01-06 13:31:22马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08比亚迪
日期:2013-12-24 15:48:09三菱
日期:2013-11-01 18:13:00劳斯莱斯
日期:2013-08-21 10:11:54红旗
日期:2013-08-02 10:40:25
7#
 楼主| 发表于 2012-4-24 09:33 | 只看该作者
lorikyo 发表于 2012-4-24 00:00
create index IDX_C on TEST_A (CREATED,OBJECT_ID);  把created 放前面!

法师 不行的 oralce 9I first_rows  当数据量大的时候 有order by  就只会走order by 的字段(order by 的字段有索引的话)

使用道具 举报

回复
论坛徽章:
12
复活蛋
日期:2012-11-19 08:22:46妮可·罗宾
日期:2016-10-12 10:02:44沸羊羊
日期:2015-02-12 09:39:42马上有车
日期:2015-01-06 13:31:22马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08比亚迪
日期:2013-12-24 15:48:09三菱
日期:2013-11-01 18:13:00劳斯莱斯
日期:2013-08-21 10:11:54红旗
日期:2013-08-02 10:40:25
8#
 楼主| 发表于 2012-4-24 09:36 | 只看该作者
dotaddjj 发表于 2012-4-24 00:40
oralce 9I下默认cbo认为排序是非常消耗内存的,默认应该是最高,所以你后面的order by create,oracle会选择 ...

飞鱼马甲?

使用道具 举报

回复
论坛徽章:
19
ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292015年新春福章
日期:2015-03-04 14:53:16优秀写手
日期:2014-03-19 06:00:24马上有对象
日期:2014-02-18 16:44:082014年新春福章
日期:2014-02-18 16:44:08比亚迪
日期:2013-10-23 21:35:02ITPUB社区12周年站庆徽章
日期:2013-10-08 14:54:39茶鸡蛋
日期:2013-07-25 19:48:40灰彻蛋
日期:2013-05-24 09:42:412013年新春福章
日期:2013-02-25 14:51:24
9#
发表于 2012-4-24 09:43 | 只看该作者

我想问的一个问题是,LZ 何以认为组合索引就会比 做单列索引快?

排序是一个耗时耗资源的操作,任何数据库都会尽量避免排序操作。

LZ 可以试试使用hints ,看看是否可强制SQL 走组合索引。

使用道具 举报

回复
求职 : 数据库管理员
论坛徽章:
10
ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292014年新春福章
日期:2014-02-18 16:44:08优秀写手
日期:2013-12-27 06:00:12ITPUB社区千里马徽章
日期:2013-06-09 10:15:342013年新春福章
日期:2013-02-25 14:51:24奥运纪念徽章
日期:2012-11-28 09:33:31奥运纪念徽章
日期:2012-11-20 10:27:31ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42马上有对象
日期:2014-02-18 16:44:08
10#
发表于 2012-4-24 09:51 | 只看该作者
ahdong2007 发表于 2012-4-24 09:43
我想问的一个问题是,LZ 何以认为组合索引就会比 做单列索引快?

排序是一个耗时耗资源的操作,任何数 ...

oracle 9I下_sort_elimination_cost_ratio隐含参数默认为0,oracle认为排序消耗巨大,就很自然的避免了排序,而使用了有索引的列来避免排序,而一般组合索引肯定比单列索引效率高,这是必然。oracle 10g下已经修改此隐含参数为1.

使用道具 举报

回复

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

本版积分规则 发表回复

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