楼主: jimmylee

[精华] 为什么加上索引速度奇慢无比?

[复制链接]
论坛徽章:
2
授权会员
日期:2005-10-30 17:05:33ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32
41#
发表于 2002-8-1 09:12 | 只看该作者
From your explain plan, I can tell that you did not analyze your index since there's no cost.  It used RBO, not CBO.  

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 VIEW
2 1 COUNT
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'CSTMONILOG'
4 3 INDEX (FULL SCAN) OF 'INDEX_CSTMOINILOG_MONITIME' (N
ON-UNIQUE)

使用道具 举报

回复
论坛徽章:
2
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33
42#
 楼主| 发表于 2002-8-1 09:47 | 只看该作者

Re: 给你一点建议:

最初由 biti_rainy 发布
[B]把你的这个查询拆开

利用他的这个办法把 rowid  的集合(这个集合可以顺便把索引字段一起取出来)取出来,比如30条
不使用in
1:
然后用rowid做条件循环30次取30条记录
2:或者循环,利用取出的索引字段然后循环取30条记录,根据索引条件

或者:利用这个集合做驱动表跟表做表连接(不使用in) [/B]


我按照你的建议,将语句改为:
select a.rowid , a.MONI_TIME,a.MONI_TYPE,a.MONI_APERRCODE,a.MONI_CONSTANT,SubStr(a.MONI_USERINFO,1,50) MONI_USERINFO
from cstmonilog2 a ,(select rid from (select rownum rno,rowid /*+ INDEX(cstmonilog2 index1 ) */ rid
  from cstmonilog2 where MONI_AREA = '9' and MONI_TYPEID = '1' and MONI_FLAG = '1'
  and rownum <990035
  order by MONI_TIME) where rNo >=990000) b
  where a.rowid=b.rid
  order by a.moni_time
不知道是否正确。这个语句与lwxian的执行的时间基本一样,相互差别不超过20ms。所以没有明显的改善。另外你说的cursor方式如何去做?如何对最终的结果集排序?

使用道具 举报

回复
论坛徽章:
2
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33
43#
 楼主| 发表于 2002-8-1 09:49 | 只看该作者
最初由 yanwang 发布
[B]From your explain plan, I can tell that you did not analyze your index since there's no cost.  It used RBO, not CBO.  
[/B]

是的,用cbo挺费神的。

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
44#
发表于 2002-8-1 09:53 | 只看该作者

o

关键在于这个:
select rid from (select rownum rno,rowid /*+ INDEX(cstmonilog2 index1 ) */ rid
from cstmonilog2 where MONI_AREA = '9' and MONI_TYPEID = '1' and MONI_FLAG = '1'
and rownum <990035
order by MONI_TIME) where rNo >=990000

这一步的时间很重要
如果这个时间长,那就没有办法了!
在这一步里面去调整索引和一些东西,如果这个结果返回的快,那么就有戏

因为毕竟这里返回的结果集很有限
然后根据这个结果集为游标,用这个结果集里面的有限的值(rowid  或者  索引字段)

然后循环单条查询基表(这个时候可通过rowid 或者 索引去确定记录)

使用道具 举报

回复
论坛徽章:
2
ITPUB元老
日期:2005-02-28 12:57:00授权会员
日期:2005-10-30 17:05:33
45#
 楼主| 发表于 2002-8-1 10:08 | 只看该作者
是的,如何改进呢?

使用道具 举报

回复
hahaer 该用户已被删除
46#
发表于 2002-8-1 10:13 | 只看该作者
哎,连hints的位置都不对。跟别说~~~~~~~~~~

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
47#
发表于 2002-8-1 10:19 | 只看该作者

什么如何改进?

你先测试了
select rid from (select rownum rno,rowid /*+ INDEX(cstmonilog2 index1 ) */ rid
from cstmonilog2 where MONI_AREA = '9' and MONI_TYPEID = '1' and MONI_FLAG = '1'
and rownum <990035
order by MONI_TIME) where rNo >=990000
很慢?
如果这个很慢
MONI_AREA  的不同值有多少?
如果不同值很少
建议把时间字段放在索引的最前面试一下

把信息交代清楚一点,不要交互次数太多,  ok?

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
48#
发表于 2002-8-1 10:33 | 只看该作者

呵呵

事实上我确实没有去核实  hints 这样写是否是正确的
因为别人写了,而主人又说见着了效果,那我姑且就认为是对的了

如果这样的话
可以考虑把该表分开存储,有关索引和排序部分的拆成小的存储

也可以参考 IOT 部分内容

最根本的目的,就是确定你翻页的记录的时候,不把所有内容扫入内存

使用道具 举报

回复
hahaer 该用户已被删除
49#
发表于 2002-8-1 10:47 | 只看该作者

Re: Re: 给你一点建议:


最初由 jimmylee 发布
[B]

我按照你的建议,将语句改为:
select a.rowid , a.MONI_TIME,a.MONI_TYPE,a.MONI_APERRCODE,a.MONI_CONSTANT,
        SubStr(a.MONI_USERINFO,1,50) MONI_USERINFO
   from cstmonilog2 a ,
       (select rid from ( select rownum rno,rowid /*+ INDEX(cstmonilog2 index1 ) */ rid
                            from cstmonilog2
                            where MONI_AREA = '9'
                              and MONI_TYPEID = '1' and MONI_FLAG = '1'                                
                              and rownum <990035                                              -- 1
                              order by MONI_TIME )                                            -- 1  
          where rNo >=990000) b
  where a.rowid=b.rid
  order by a.moni_time
不知道是否正确。这个语句与lwxian的执行的时间基本一样,相互差别不超过20ms。所以没有明显的改善。另外你说的cursor方式如何去做?如何对最终的结果集排序? [/B]


The Statement given above has 4 problems at least:
1. the resultset is not what you want:  the line mared with '--1' shows that the statement will cut down the result set to 990035 before order them. the resultset from this statement is uncertain. It will be diffrent according the indexes used or something else. Is it you want? I doubt.
2. the hints location is not proper. it should only be setted after select/update/insert directly except push_predicates. However, in this problem, it will use the index1 even you don't have hints in the subquery.
3. this statement added more logic while it actually not need. NESTED LOOP
4. why don't u use CBO. it should work much smarter in you problem.


but I aggree this statement has improved, it at lease omit the unnessary unique operation when using IN.

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
50#
发表于 2002-8-1 10:57 | 只看该作者

:)

还是楼上的仔细  

我根本就没有注意sql的逻辑上的问题
只是个人根本不关心这个问题,而只是关心了怎么才能提高速度

事实上使用 rownum 肯定需要三层的 inline view
只有使用 row_number()  over() 才能在两层里面解决问题,但只有816以上版本才支持
我想我只是建议了思路,所有的sql都是从原文copy过来的  

使用道具 举报

回复

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

本版积分规则 发表回复

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