2011-06-09 65 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