对于一个很大的数据库表,查询时不能利用索引怎么办?环境:
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')
各位大侠,谁有好办法解决这个问题呢,高分赠上。

解决方案 »

  1.   

    感觉跟你从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优化器,而直接采用基于规则或者基于成本的优化器. 
      

  2.   

    --利用Hint强制指定索引,或者删除索引重新建立试试,首先说明:某些情况用上索引的速度反然慢
    --Hint强制指定索引 ,如Select /*+index(表名称,索引名称) */ * from 表名 where 条件 
      

  3.   

    tStkPc说说这个列的数据分布情况.使用10053来trace出来这条语句的信息.然后把trace中的核心内容帖上来看一下.另外.9201这个版本bug不少.如果有条件的话可以升级至9206以上.
      

  4.   

    应该还是统计信息的问题, 把你的其他数据库中tStkPc 表及其索引的统计信息导入到你的问题库中试试;
    另外你在问题库中是如何搜集统计信息的? 有没有搜集直方图? 有的话去掉直方图再搜集试试.
      

  5.   

    你可以查看如下方面:
    1.是否使用了CBO.
    2.是否所有相关表的统计信息都收集了,如果只收集了一部分表那么很可能有问题.
    2.是否收集了索引的统计信息.
    3.表的字段类型是否有问题,比如JsCode是否是字符型的,plsid字段两表中是否类型一致.
    如果还不行那么把10053的trace打出来大家看看吧.ps:强烈建议你升级版本,9.2.0.1有很多bug,非常多.
      

  6.   

    我升级到9.2.0.6以后,的确有所改善,但还没有彻底解决。
    在升级到9.2.0.6后,这个表的统计信息重新统计后,索引还是不能良好利用,没有办法,将这个表数据备份后drop了,然后在创建一下,再在oracle中插入数据,就好了。现在还有问题,这个表有时候还会变坏,导致索引利用不上,重建索引就好。
    我们在10g上也遇到了类似的问题,但10g只要填充数据后,重新统计一下数据即可正常使用,而且永不坏。还有一个消息,那就是使用了双机热备软件,在两个服务器之间切换服务时,容易造成表损坏。
      

  7.   

    情况的进一步说明:
    JsCode是字符类型的,PluID是number类型的。
    tStkPc表中存储了tDstDpsData中OrgCode、PluID中各种条件、各个时期下的数据,数据量很大。