select count(F_CDR_RATE_REC_ID), sum(F_RATE_UNITS), sum(F_RATE_FEE)
     from A, B
       where (to_char(A.CREATE_TIME, 'yyyy-mm-dd')>= :b_date    
          and to_char(A.CREATE_TIME <= :e_date) 
           and (A.P_ID = :p_id)
             AND (A.GROUP = B.GROUP) 
              And(A.ITEM= B.ITEM)
                 AND (B.TYPE_ID = 
                        select TYPE_ID from C
                          where C.TYPE_ID IN
                            (2,7,20,61,62,65,66);   要做的是一个统计操作,其中A表记录有千万级别,B表和C表记录都不多,但估计是在做表连接时使得操作的记录数以倍增,执行速度太慢,不知大侠们有什么高招? 

解决方案 »

  1.   

    用工具软件 Sql expert for Oracle,它能根据数据库现有的索引自动优化Sql,提供一条最优的SQL语句。
      

  2.   

    1。如果使用A.p_id可以确定到很少的行,A.p_id应该使用索引.
    2。如果a.create_time可以用来辅助减少确定出来的记录数,该字段也可建立索引,同时应该避免在字段上使用内嵌函数,将to_char改为用在:b_date,:e_date上的to_date函数。
    3.
    B.TYPE_ID = select TYPE_ID from C
                 where C.TYPE_ID IN
               (2,7,20,61,62,65,66)
    为何不直接用
    B.TYPE_ID IN (2,7,20,61,62,65,66) ?一定要保证这些id在C表存在吗?
      

  3.   

    where (to_char(A.CREATE_TIME, 'yyyy-mm-dd')>= :b_date    
              and to_char(A.CREATE_TIME <= :e_date) 不好,问题:
    你有100000条记录就要调用to_char1000000次,你应该改为:
    A.CREATE_TIME>=to_date(:b_date,'yyyy-mm-dd')
      

  4.   

    count(F_CDR_RATE_REC_ID), 如果你是求记录数,这样写不好,改为:
    count(*) 或 sum(1)
      

  5.   

    表连接的语句(a.group=b.group and a.term=b.term)写在where子句的前面.表的限制条件越严格的写得越后.
      

  6.   

    (to_char(A.CREATE_TIME, 'yyyy-mm-dd')>= :b_date    
    and to_char(A.CREATE_TIME <= :e_date) 
    这两个条件是会严重影响性能的,解决办法有两个
    1。大力的方法 不要在索引列上面使用函数
    2。创建函数索引
    例如:create index idx_create_time on a(to_char(A.CREATE_TIME, 'yyyy-mm-dd'));
      

  7.   

    假如你的create_time有索引,將to_char-->to_date