|
藍森林 http://www.lslnet.com 2006年8月26日 15:18
跪求海量數據的查詢問題解決方案!!
這個問題用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業務分別放在不同的數據庫上 |
| |