有个大表,大概2千w--3亿条数据,安每天日期做了分割,现在大概有5个sql执行起来很费劲,其他的业务也不太用这个大表。
所以想加索引。但是不知道怎么加好。
方案1:打算分别按照5个sql的where条件,分别建立联合索引,就是where条件是什么就建什么字段的联合索引
方案2:把所有5个sql的where条件都分别建立索引,就是把where条件中字段都挨个建索引例如:sql如下:
select TO_CHAR(TIMEVALUEfiled, 'YYYY-MM'),COUNT(OLDfiled),INFOVALUEfiled 
from BigTable where
TYPEfiled = "xxx" and 
INFOfiled = "xxx" and 
CRETIMEfiled >= to_date('xxx','yyyy-mm-dd hh24:mi:ss')  and 
CRETIMEfiled <= to_date('xxx','yyyy-mm-dd hh24:mi:ss')  
group by INFOVALUEfiled,......
如果按照方案1:则将 TYPEfiled、INFOfiled、CRETIMEfiled 建立一个联合索引。
如果按照方案2:则将 TYPEfiled、INFOfiled、CRETIMEfiled 分别建立索引。
不知道根据我们的需求用那个方案比较好。db小菜鸟啊~希望大家帮忙看看啊~555

解决方案 »

  1.   

    如果你where后面的条件不经常改动,而且是个枚举型的,建议楼主建立位图索引!
      

  2.   

    group by INFOVALUEfiled,......这里的列,也得建 索引啊。
      

  3.   

    联合索引一般用在 where后面 位置不变的 而且查询次数比较多的 用联合索引比较好 联合索引最主要的是查询字段的位置一定要一样,不能改变位置 改变了联合索引就失效了
      

  4.   

    你的数据是按照分区管理的,所以看看能不能用LOCAL INDEX。
    要是不能用LOACAL INDEX的话,每当你去掉一个分区的话,你得从新更新全部INDEX,这个要是数据量大的话很花时间的。
    还有我看你的查询条件里面有日期,这个日期跟分区时候的日期是一样的吗??一样的话你在查询的时候可以指定他的分区,这样会快很多。
    你的Oracle版本要是9.2以上的话,一般采用的是基于代价的优化器(CBO),这样的话你可以无视5楼的话了。CBO的时候,跟位置没什么关系的。
    你上面给的SQL语句要是对的话,不用考虑位图索引,不是枚举。
    你现在主要是看看能不能用LOCAL索引,这样当你分区表改变的时候容易维护。
    要是能用联合索引,就用联合索引,比单列索引快。还有在执行计划的稳定上也有好处。但是联合索引有一些限制,你看看资料。
      

  5.   


    可以考虑用分区表,建分区索引。 分区索引Oracle 会自动管理。参考: Oracle 分区表
    http://blog.csdn.net/tianlesoftware/archive/2009/10/24/4717318.aspx------------------------------------------------------------------------------ 
    Blog: http://blog.csdn.net/tianlesoftware 
    网上资源: http://tianlesoftware.download.csdn.net 
    相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx 
    DBA1 群:62697716(满); DBA2 群:62697977
      

  6.   

    对于local索引,每一个表分区对应一个索引分区,当表的分区发生变化时,索引的维护由Oracle自动进行。对于global索引,可以选择是否分区,而且索引的分区可以不与表分区相对应。当对分区进行维护操作时,通常会导致全局索引的INVALDED,必须在执行完操作后 REBUILD。看的不是太明白。
    是不是按照这个逻辑我建立分区索引比较好呢?分区索引具体怎么建立啊?要注意什么啊?
      

  7.   

    不是每个字段都要建立索引,关键是要查看每个列值的选择性,
    如果单列的选择性低,可考虑建立组合索引,
    建立本地分区索引使用local关键字就行了
    如:create index idx_TYPEfiled on TYPEfiled(BigTable) local;
      

  8.   

    感谢啊还有几个问题想问下。
    1、那如果select的时候需要跨了所有的分区,检索的时候分区索引还是否有效?
    2、建立联合索引就把where条件后面的字段和group后面的都加上就行了吧?如果建立多个联合索引,会不会对插入数据时有很大的影响?
      

  9.   

    对于local索引,每一个表分区对应一个索引分区,当表的分区发生变化时,索引的维护由Oracle自动进行。对于global索引,可以选择是否分区,而且索引的分区可以不与表分区相对应。当对分区进行维护操作时,通常会导致全局索引的INVALDED,必须在执行完操作后 REBUILD。看的不是太明白。
    是不是按照这个逻辑我建立分区索引比较好呢?分区索引具体怎么建立啊?要注意什么啊?
      

  10.   

    1 你先把5个SQL 贴出来
    2 CRETIMEfiled >= to_date('xxx','yyyy-mm-dd hh24:mi:ss')  and 
    CRETIMEfiled <= to_date('xxx','yyyy-mm-dd hh24:mi:ss') 
     一般情况下是多长的时间?
    表是如何分区的?3 TYPEfiled = "xxx" INFOfiled = "xxx" 两个字段的有多少个不同值最后我很幸运地告诉你 我也在玩2千万到1.7亿的数据表。
    1 我的表是按时间 按月分区
    2 我的SQL 按时间来查的话 基本上是按月和按周。 在这个时间字段建立了个分区索引。 按周按月的统计不用索引,而按3-7天就走索引。3 TYPEfiled INFOfiled 使用位图组合索引。你可以先把索引建立起来后 再测试5个SQL的执行计划。
      

  11.   

    索引多了 反而会让ORACLE 误会,错误选择索引。从而导致索引顺序读
      

  12.   

    感谢啊还有几个问题想问下。
    1、那如果select的时候需要跨了所有的分区,检索的时候分区索引还是否有效?
    2、建立联合索引就把where条件后面的字段和group后面的都加上就行了吧?如果建立多个联合索引,会不会对插入数据时有很大的影响?
    3 对于local索引,每一个表分区对应一个索引分区,当表的分区发生变化时,索引的维护由Oracle自动进行。对于global索引,可以选择是否分区,而且索引的分区可以不与表分区相对应。当对分区进行维护操作时,通常会导致全局索引的INVALDED,必须在执行完操作后 REBUILD。
    看的不是太明白。
    是不是按照这个逻辑我建立分区索引比较好呢?分区索引具体怎么建立啊?要注意什么啊?
    ------
    1 关键是看你选择的列都在索引中吗? 在就走索引,不在就走表。还是看IO成本大小。
    2 where的字段跟group 字段 不一样。 where是过滤数据。group是分组数据,排序。
      group上的字段建了索引,其实降低了排序IO 因为索引是有序的,表是无序的。
    3 分区索引: 本地分区和全局分区。 本地分区是根据表的分区字段来分区,所以oracle自动维护。而全局分区是用户根据其他字段来分区,自然由用户来维护。
      

  13.   

    2 我的SQL 按时间来查的话 基本上是按月和按周。 在这个时间字段建立了个分区索引。 按周按月的统计不用索引,而按3-7天就走索引。
    为什么按周、月统计你反而不用索引了呢?周月的数据量不是比天更大吗?为什么反而不用索引呢?