对于一个很大的数据库表,查询时不能利用索引怎么办?

JYCheng 2007-09-29 09:55:48
对于一个很大的数据库表,查询时不能利用索引怎么办?

环境:
Oracle:9.2.0.1 for Windows2003Server

表1:tStkPc
索引:Idx_tStkPc OrgCode\PluID\ExPluCode
记录数:4,412,381

表2:tDstDpsData
记录数:10000

我的脚本如下:
select * from tDstDpsData T
where Exists(select 1 from tStkPc where OrgCode=T.OrgCode and PluID=T.PluID and JsCode='2')

在我们的十几个数据库中,这个语句肯定会利用索引Idx_tStkPc,从而可以保证查询速度比较快。但是另外一个服务器上的数据库中的数据是刚从MSSQL2000转移过来的,在执行这个语句时,就不能使用索引,速度奇慢。
我们在这个基础上,对数据库执行了统计,此时oracle肯定就根据Cost模式得到执行计划。我们仔细看了,oracle认为全表扫描的成本时756,而利用索引的成本是83031。
为了解决这个问题,我们把sStkPc表Drop后重新创建、重新建立索引、重新更新统计信息,但都不管用。
我还尝试了另外一种写法,就是强制指定索引,语句如下,执行效果比较好,但在我的程序中,有太多地方利用表tStkPc了,基本上都是这种用法,要修改就太困难了。
select * from tDstDpsData T
where Exists(select /*+ Index(tStkPc IDX_TSTKPC)*/ 1 from tStkPc where OrgCode=T.OrgCode and PluID=T.PluID and JsCode='2')
各位大侠,谁有好办法解决这个问题呢,高分赠上。
...全文
307 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
knowledge_Is_Life 2008-05-01
  • 打赏
  • 举报
回复
关注 接分
meiZiNick 2008-04-30
  • 打赏
  • 举报
回复
我也想了解,谢谢LZ.
JYCheng 2007-10-11
  • 打赏
  • 举报
回复
情况的进一步说明:
JsCode是字符类型的,PluID是number类型的。
tStkPc表中存储了tDstDpsData中OrgCode、PluID中各种条件、各个时期下的数据,数据量很大。


JYCheng 2007-10-11
  • 打赏
  • 举报
回复
我升级到9.2.0.6以后,的确有所改善,但还没有彻底解决。
在升级到9.2.0.6后,这个表的统计信息重新统计后,索引还是不能良好利用,没有办法,将这个表数据备份后drop了,然后在创建一下,再在oracle中插入数据,就好了。现在还有问题,这个表有时候还会变坏,导致索引利用不上,重建索引就好。
我们在10g上也遇到了类似的问题,但10g只要填充数据后,重新统计一下数据即可正常使用,而且永不坏。

还有一个消息,那就是使用了双机热备软件,在两个服务器之间切换服务时,容易造成表损坏。
凤影 2007-10-01
  • 打赏
  • 举报
回复
你可以查看如下方面:
1.是否使用了CBO.
2.是否所有相关表的统计信息都收集了,如果只收集了一部分表那么很可能有问题.
2.是否收集了索引的统计信息.
3.表的字段类型是否有问题,比如JsCode是否是字符型的,plsid字段两表中是否类型一致.


如果还不行那么把10053的trace打出来大家看看吧.

ps:强烈建议你升级版本,9.2.0.1有很多bug,非常多.
liuyi8903 2007-09-30
  • 打赏
  • 举报
回复
tStkPc

说说这个列的数据分布情况.

使用10053来trace出来这条语句的信息.

然后把trace中的核心内容帖上来看一下.

另外.9201这个版本bug不少.如果有条件的话可以升级至9206以上.
WangZWang 2007-09-30
  • 打赏
  • 举报
回复
--利用Hint强制指定索引,或者删除索引重新建立试试,首先说明:某些情况用上索引的速度反然慢
--Hint强制指定索引 ,如

Select /*+index(表名称,索引名称) */ * from 表名 where 条件
kinglht 2007-09-30
  • 打赏
  • 举报
回复
感觉跟你从MSSQL2000转移过来没关系,并且重建表和索引都不行,建议你查看一下你那个数据库的优化器:

ORACLE的优化器共有3种:

a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性)



设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖.

为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性.

如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器.



在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.
kongkongye 2007-09-30
  • 打赏
  • 举报
回复
应该还是统计信息的问题, 把你的其他数据库中tStkPc 表及其索引的统计信息导入到你的问题库中试试;
另外你在问题库中是如何搜集统计信息的? 有没有搜集直方图? 有的话去掉直方图再搜集试试.

3,490

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧