一张销售事实表,一年1亿多条记录,有一个时间的维度表,里面有sale_date,month,week。现在想汇总每个月的销售额
sql:select sale_month, sum(sale_money) from sales,times 
where sales.sale_time = times.sale_time and sales.sale_time > to_date('20100101','yyyymmdd') 
group by sale_monthsales表,times表上分别在sale_date 建立了一个索引。现在的问题是,由于用到了times表中的sale_month分组,sales会被全表扫描,效率不高。请问应该如何优化?
谢谢

解决方案 »

  1.   

    ORACLE版本?sales.sale_time > to_date('20100101','yyyymmdd')数据占整个表比例如何?
    如果是10g,ORACLE应该会选择最优CBO获取执行计划。走索引不一定就一定快,若你想强制走索引,用hint试试,比较俩执行计划,哪个更优。
      

  2.   

    在sale_time上有分区表,每年一个分区。 我是说如果从数据库表设计角度看,还可以优化么?这么点的数据量很多数据仓库都会遇到吧,看来真要用物化视图+dimension ?
      

  3.   


    我们这边的处理方法  对于有些不是 非常大的表 一般采用 用月 进行分区 比如账单 之类的  
    对于很大的表(一天300W+ 数据 保存1年多的 ) 采用 月分区加日分区 (术语不清楚 subpartition) 不知道 对楼主有么有用 
      

  4.   

    select to_char(sale_time,'yyyy-mm') month, sum(sale_money) from sales
    where sale_time > to_date('20100101','yyyymmdd')  
    group by to_char(sale_time,'yyyy-mm')
      

  5.   


    前一句你说错了,比较的时候索引一样可以用的,问题是group时间就有问题了
      

  6.   

    sale_date的索引变成 sale_date DESC,试一下.
      

  7.   

    接楼上,CBO会根据表的分析情报来决定执行计划.现在的表和索引的状态,决定了使用全表SCAN而不是INDEX SCAN.
    把SQL TRACE贴上来看看.
      

  8.   

    两个字段比较的意思是进行表连接吗?
    where sales.sale_time = times.sale_time
    象楼主的这样的表连接,索引是用不上的,这点可以从执行计划中看出,
    另外可以考虑以天为单位分区。
    分区最简便的方法是先建分区表,后把数据insert