天堂的狼

更好的生活,来自不懈的努力与拼搏,不要仅仅看中结果,拼搏的过程同样是精彩的!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
这个问题用oracle该如何解决??

我需要用数据库存储中国移动的一些wap日志。
比较变态的需求是:需要对这些日志进行统计。
选择日期,查询某段日期内符合某些特征的访问记录。

数据量的级别大概是几十亿条,几百G的数据。
每天按最少500万条的速度递增。

我做了个2000万条记录的测试。
select from where
select from group
这些查询基本无法执行下去,实在太慢了!

几十亿条的情况就不敢想了!!

怎么办?怎么办?

使用数据库的分区技术可以解决吗?
谁有此方面经验给我提点好建议吧。
另外,有哪些公司提供此方面的技术支持??

:em02::em02:
1. 用paratition和index确实很有帮助.基本能解决OLTP的需求
2. 这个应该当DW的来做..直接从OLTP抽取。基本上是搞不定的..
3. 用MV不知道行不行.你可以考虑一下..呵呵

不需要用跪求吧,不懂不是错!

不需要用跪求吧,不懂不是错!

是啊,跪了也没用,还是不会做啊!
2楼可否说的详细些?
比如给我举个案例。

用户去电信部门查自己的通话记录,也是从海量数据中抽取吧,它们是怎么做的?

那么大的数据量,没有做过,希望高手出来说说经验
个人感觉用分区表+分区索引,但是如此大的数据量,不知道效果如何!

解决方案

1。带条件的字段,添加索引
  如果带有where 条件语句的查询, 例如:
  select * from emp where sal>1000;
  create index sal_index on emp(sal);
  这样在查询满足条件sal〉1000时,就不会发生全表扫描。 而是先扫描sal索引,并找出符合条件的rowid,然后直接到表中找出记录,能大大加快查询时间。跟据你目前数据库是按照时间分段的情况。我建议你建立一个以时间字段索引
比如电话开始时间字段  telstarttime date
电话结束时间字段   telendtime  date
创建两个索引:
create index sarttime_index on telrecord(telstarttime);
create index end_index on telrecord(telstarttim);
利用索引进行查询,例查询出2006年4月6号的所有记录:
  select * from telrecord
  where telstartime>To_Date('2006/04/06 00:00:00' ,'yyyy/mm/dd HH24:mm:ss')
and telendtime<To_Date('2006/04/06 23:59:59',,'yyyy/mm/dd HH24:mm:ss') ;
这样查询的时候就会访问 sarttime_index  end_index 两个索引字段。并找出你需要的记录,可以大大降低访问时间。

2。截断数据
如果数据库中的表过于巨大,进行全表扫描会如果返回记录的数量巨大,比如几百万条数据。无论何种查询模式都不能实现快速的数据返回。一种方式就是建立分区表。按照时间段分开,比如一个月一个文件分区,这样做月统计的时候,就可以只访问一个分区的数据, 能够减轻访问的压力。

3。统计计算
可以把整体记录摘离出来,比如统计3月份的记录,可以建立一个临时表, 把符合3月份的记录先抽取出来,然后对这个临时表中的数据进行统计。这样数据库中可能有12个月的数据,我们只使用1/12的数据,可以大大加快统计的速度。

4。以空间换时间
计算速度和存储空间成反比,要提高计算的速度就要牺牲很多的空间。 统计的时候会发生这样的情况,就是要产生一系列的中间计算。如果都依靠回滚段和临时表空间来计算会非常耗费时间。需要你自己设计合理的数据库结构来提高计算的速度。
本人在一个项目当中遇到过类似情况,在记录表中增加了一个24小时字段,减少了一个临时表的生成。将统计计算时间从原先的45分钟,减少到5分钟。 效益非常可观。


建一些小的tables, 把每天的日志放到一个 table 里面。再做索引什么的。
也可以把数据分散放到几个服务器上。比如 2005年的放到 server5.
如果还不够快,可试用别的工具,如 Perl, SAS。
也可试一下作网站日志分析报告的软件,如 NetTracker (http://www.sane.com/)

利用分区表,按时间范围分区,并根据需要建立局部索引

我们这边一个呼叫中心的话单是以每月建一个表来实现的
全年12个月你就建12个表
同时使用VIEW和INDEX 问题就解决了

可以这么搞的:采用分区表模式

假设过去将来5年(2006-2010)的数据量...

首先创建5*12个LUN,一个LUN分别对用一个表空间(可以降低io),用来存放数据表,
    再创建5*12个LUN,一个LUN分别对应一个表空间,用来存放索引表。

在120个LUN上分别建立表空间:eg
create tablespace xxx_200601 DATAFILE  '/dev/rvol/rootdg/xxxx_200601' size 500M(根据实际大小) reuse extent management LOCAL UNIFORM SIZE 1M SEGMENT SPACE MANAGEMENT AUTO ;
....
在创建索引表空间的时候可以指定: nologging 加快速度。因为你的索引可能会经常rebuild的。
然后再创建分区表:
create table xxx_data (
        C_POINT_ID NUMBER(10) NOT NULL,
        C_DATA_DATE NUMBER(10) NOT NULL,
        C_DATA_FLAG NUMBER(5) NOT NULL,
        C_DATA_VALUE NUMBER(15,4) ,
        C_DATA_STATUS NUMBER(10))
        partition by range (C_DATA_DATE)
        (
        partition t_data200601
        values less than ((to_date('20060201','YYYYMMDD')-to_date('19700101','YYYYMMDD')))
        tablespace t_data200601,
        partition t_data200602
        values less than ((to_date('20060301','YYYYMMDD')-to_date('19700101','YYYYMMDD')))
    ......
       )

创建索引:
create index  xxxx_index on xxx_data(C_POINT_ID,C_DATA_DATE,C_DATA_FLAG)
        local
        (partition t_data200601 tablespace idx_data200601,
         partition t_data200602 tablespace idx_data200602,
......);

再建局部索引.....
......
这样效率会高很多的!按月来查找是不是更快哦


1楼兄弟是哪里的?假如是湖南的,可以找我的....

和楼上的几位高手意见一样,分区。

1 分区
2 优化查询
3 将olap业务和oltp业务分别放在不同的数据库上
posted on 2009-06-10 22:51  天堂的狼  阅读(681)  评论(0编辑  收藏  举报