2011-06-09 63 views
0

我已經被賦予了爲我們的網站提取所有谷歌分析數據並分析它並放入數據庫然後生成一些關於該數據的報告的任務。 問題是,我最終在表中有近2m的記錄。 這些報告由幾個SUM()和AVG查詢組成,您可以想象它們在某些情況下花費的時間太長(最壞的情況是沒有設置日期過濾器,而且範圍廣泛的標準(取決於報告的類型)需要8-10分鐘 )。 鑑於用戶將有權訪問這些報告,這次是不可接受的... 目前該項目正在使用Postgres。我非常清楚RDMS不會在10秒內處理這類數據,特別是在單臺機器上運行。處理錯誤數據庫的最佳技術(並行計算?)

問題是什麼纔是最好的選擇軟件和架構/技術來取得良好的效果?

我試過MongoDb,但是map/reduce在一臺機器上真的不能工作得更快,因爲它是單線程的(至少現在是這樣)。

我知道我可能正在調查一個並行系統,但仍然不確定... 我感覺舒服,使用mongoDB,我讀了他們正在改善很多關於聚類和使用多點頭和所有,但我會愛一個人以最有效的方式分享其他意見和經驗,不僅在計算能力方面,而且在價格方面。

謝謝

P.S. 至於一些Postgres的應該處理這個數據量我張貼一些更詳細的答案:

表結構:

-- Table: ga_content_tracking 

-- DROP TABLE ga_content_tracking; 

CREATE TABLE ga_content_tracking 
(
    id serial NOT NULL, 
    country character varying(255), 
    city character varying(255), 
    page_title character varying(255), 
    page_path character varying(255), 
    source character varying(255), 
    referral_path character varying(255), 
    date date NOT NULL, 
    visits integer, 
    pageviews integer, 
    avgtime_on_site double precision, 
    yacht_id integer, 
    charter_listing boolean DEFAULT false, 
    sales_listing boolean DEFAULT false, 
    directory_listing boolean DEFAULT false, 
    news_related boolean DEFAULT false, 
    visitor_type character varying(30), 
    organisation_id integer 
) 
WITH OIDS; 
ALTER TABLE ga_content_tracking OWNER TO postgres; 

-- Index: ga_content_tracking_charter_listing 

-- DROP INDEX ga_content_tracking_charter_listing; 

CREATE INDEX ga_content_tracking_charter_listing 
    ON ga_content_tracking 
    USING btree 
    (charter_listing); 

-- Index: ga_content_tracking_country 

-- DROP INDEX ga_content_tracking_country; 

CREATE INDEX ga_content_tracking_country 
    ON ga_content_tracking 
    USING btree 
    (country); 

-- Index: ga_content_tracking_dates 

-- DROP INDEX ga_content_tracking_dates; 

CREATE INDEX ga_content_tracking_dates 
    ON ga_content_tracking 
    USING btree 
    (date); 

-- Index: ga_content_tracking_directory_listing 

-- DROP INDEX ga_content_tracking_directory_listing; 

CREATE INDEX ga_content_tracking_directory_listing 
    ON ga_content_tracking 
    USING btree 
    (directory_listing); 

-- Index: ga_content_tracking_news_related 

-- DROP INDEX ga_content_tracking_news_related; 

CREATE INDEX ga_content_tracking_news_related 
    ON ga_content_tracking 
    USING btree 
    (news_related); 

-- Index: ga_content_tracking_organisation_id 

-- DROP INDEX ga_content_tracking_organisation_id; 

CREATE INDEX ga_content_tracking_organisation_id 
    ON ga_content_tracking 
    USING btree 
    (organisation_id); 

-- Index: ga_content_tracking_sales_listing 

-- DROP INDEX ga_content_tracking_sales_listing; 

CREATE INDEX ga_content_tracking_sales_listing 
    ON ga_content_tracking 
    USING btree 
    (sales_listing); 

-- Index: ga_content_tracking_visitor_type 

-- DROP INDEX ga_content_tracking_visitor_type; 

CREATE INDEX ga_content_tracking_visitor_type 
    ON ga_content_tracking 
    USING btree 
    (visitor_type); 

-- Index: ga_content_tracking_yacht_id 

-- DROP INDEX ga_content_tracking_yacht_id; 

CREATE INDEX ga_content_tracking_yacht_id 
    ON ga_content_tracking 
    USING btree 
    (yacht_id); 

實例查詢:

superyachts=# SELECT SUM(pageviews) as cnt, SUM(visits) as cnt1, AVG(avgtime_on_site) as avg1 FROM ga_content_tracking gact WHERE TRUE AND (yacht_id IN (7727, 7600, 2352, 7735, 7735, 3739, 7620, 7631, 7633, 7775, 3688, 7779, 3930, 2884, 2724, 2547, 3465, 2324, 4981, 2369, 7820, 4772, 7802, 7249, 4364, 7623, 7803, 7804, 7805, 7957, 7728, 7728, 7252, 8044, 8067, 8016, 8017, 8019, 2726, 2726, 2233, 4549, 6021, 8286, 4773, 8326, 8312, 4881, 8349, 2223, 4387, 2697, 6224, 5947, 4967, 3031, 7494, 7497, 3833, 6594, 6608, 3587, 6599, 3160, 4934, 3122, 4895, 3505, 4980, 8360, 2311, 4885, 2660, 5260, 2362, 2783, 2992, 3286, 3434, 4849, 4117, 2179, 5002, 2187, 5006, 2266, 4900, 4069, 6219, 2951, 3317, 3474, 6218, 3847, 4745, 6480, 4498, 6094, 6312, 6092, 7221, 7220, 2257, 4883, 6518, 2597, 4902, 2638, 2690, 4872, 2790, 6221, 2881, 2887, 3082, 3131, 3141, 3166, 3166, 4887, 4979, 3295, 4886, 4875, 6516, 5005, 3400, 3401, 4990, 3489, 5007, 4882, 4899, 5116, 4082, 4970, 3760, 2202, 2411, 2605, 6291, 6513, 7176, 3029, 8412, 2064, 7826, 4876, 4949, 3626, 5587, 8554, 2837, 5086, 5118, 2058, 4484, 4041, 2953, 8136, 2490, 3291, 4991, 2611, 3590) OR organisation_id = 1) ; 
    cnt | cnt1 |  avg1  
--------+-------+----------------- 
640826 | 46418 | 34.408638690454 
(1 row) 

Time: 114652.334 ms 
+1

「需要8-10分鐘」 - 這對於在200萬條記錄上運行大型報告似乎相當合理。 – 2011-06-09 12:03:07

+0

不是真的可以接受 – StanV 2011-06-09 13:51:14

+0

什麼PG版?你的桌子真空分析了嗎?請在explain.depesz.com上發佈解釋分析或鏈接。當我閱讀你的索引時,你的查詢應該使用帶有大胖濾鏡的seq掃描。 – 2011-06-09 14:01:21

回答

1

我我還沒有意識到沒有RDMS能夠處理10秒內的這類數據,特別是在單臺機器上運行。

我不知道你來自哪裏得到你的假設......

test=# create table test (id int not null); 
CREATE TABLE 
test=# insert into test select i from generate_series(1,2000000) i; 
INSERT 0 2000000 
test=# alter table test add primary key (id); 
NOTICE: ALTER TABLE/ADD PRIMARY KEY will create implicit index "test_pkey" for table "test" 
ALTER TABLE 
test=# vacuum analyze test; 
VACUUM 
test=# \timing 
Timing is on. 
test=# select sum(id), avg(id) from test; 
     sum  |   avg   
---------------+---------------------- 
2000001000000 | 1000000.500000000000 
(1 row) 

Time: 566.079 ms 
test=# select sum(t1.id), avg(t1.id) from test t1 natural join test t2; 
     sum  |   avg   
---------------+---------------------- 
2000001000000 | 1000000.500000000000 
(1 row) 

Time: 5891.536 ms 

以上是PostgreSQL的9.1-β在5歲的MacBook上運行(而不是連親一口,在那)。正如你所看到的,它會在半秒內吞下2M行,並且在6秒之內加入2M x 2M行。要點是,即使在一臺機器上,Postgres也會樂於在10秒內處理這種數據。

+0

我編輯了我的問題的一些細節,所以如果你能告訴我在哪裏我做錯了什麼... – StanV 2011-06-09 13:53:03

0

我同意Denis PostgreSQL不應該有幾百萬行有太多麻煩。但是,您也可以將用戶添加到Google Analytics,並讓他們針對Google的服務器運行。

漂亮的顏色可能會讓他們長時間脫離頭髮。

+0

試圖說服老闆,這是浪費時間,但他只是不會聽..這是他想要的,將GA遺傳到項目的後端,以便用戶可以執行自定義報告... – StanV 2011-06-09 13:57:08