2011-11-06 177 views
1

我写了一个统计/跟踪平台来监控我的网站活动。对于每个用户,在表格中创建一个条目,其中包含一些相关信息:IP,Ref,GeoLocate,countrycode等。如何管理庞大的数据库(MySQL)

数据库包含超过7MM的结果,大小约为4GB。

现在,我有一个脚本,必须执行SUM查询才能获得定义时间间隔($ from_date & $ to_date)的展示次数,点击次数等。

$query = "SELECT COUNT(ip) as tot, sum(clicked=0) as a0, sum(clicked=1) as a1, sum(converted=0) as a2, sum(converted=1) as a3 FROM tf_data WHERE cid='".$cid."' and stamp between ".$from_date." and ".$to_date." "; 

一个这个查询需要永久加载,即使我在一个体面的VPS机器上。在我的摘要页面中,我还有其他一些查询,这会导致脚本经常超时(REQUEST TIMEOUT:此请求需要很长时间才能处理,它由服务器超时,如果不应该超时,请联系管理员本网站增加“连接超时”。)

我该怎么办?我如何处理这些庞大的数据?我应该创建一个单独的表并运行cron作业插入/更新展示次数,请点击数字...?

这样的事情通常如何进行?

一如既往的感谢!

编辑:表结构:

CREATE TABLE `tf_data` (
`click_id` int(11) NOT NULL AUTO_INCREMENT, 
`ip` varchar(225) NOT NULL, 
`agent` text NOT NULL, 
`referer` text NOT NULL, 
`stamp` text NOT NULL, 
`country` varchar(30) NOT NULL, 
`src` text NOT NULL, 
`adspot` varchar(250) NOT NULL, 
`cid` text NOT NULL, 
`adid` text NOT NULL, 
`lp` varchar(250) NOT NULL, 
`offer` int(11) NOT NULL, 
`clicked` int(11) NOT NULL, 
`converted` int(11) NOT NULL, 
`converted2` int(11) NOT NULL, 
`price` varchar(255) NOT NULL, 
PRIMARY KEY (`click_id`), 
UNIQUE KEY `ip` (`ip`) 
) ENGINE=MyISAM AUTO_INCREMENT=9599999 DEFAULT CHARSET=latin1 
+0

你有'邮票'的索引吗? – nico

+0

你可以发布你的表结构'SHOW CREATE TABLE tf_data'吗? – Konerak

+0

也许您应该转移到OLAP数据库以汇总数据。像palo http://en.wikipedia.org/wiki/Palo_(OLAP_database),微软分析服务,画面软件,... – danihp

回答

4

首先,如果邮票是你的时间戳(我假设它是),它转换成这样,把一个指标就可以了,这样可以让你更轻松地访问数据的小子集(按日期)。

然后创建一个汇总表并对所有现有数据每天进行一次计算,然后每天做一次工作以保持最新状态。

这样,历史使用情况,您只需要看看(更小的)汇总表,并可能在自上次概要新行。

如果您并不总是需要查看所有数据,那么您也可以考虑查看表格分区(无论是built in还是穷人),这样您仍然可以在需要时引用所有数据但是只有在速度要求时才能访问它的一个子集。

1

我建议离线计算+表分区+哈希索引上邮票CID和B树索引作为一个快速的解决方案。长期解决方案是使用NoSQL数据存储解决方案,例如Cassandra,也许可以使用Hadoop + Pig来计算并将数据推送到Cassandra。

2

700万行并不是那么多。正常的WHERE子句返回多少行?

每当您遇到查询性能问题时,look at the query execution plan

问问自己:“我有正确的数据类型吗?”正如Matthew Watson指出的那样,该表中没有时间戳(DATETIME)数据类型。在这种情况下,使用DATETIME而不是TEXT可能会将数据库的大小减少每行大约10个字节。 (我猜“邮票”可能是DATE而不是DATETIME,节省的不多,但仍然可以节省,并且不需要进行日期比较)

问问自己:“我可以改进索引吗?“你至少需要”cid“和”stamp“上的索引

问问自己,”我可以减少基表中还是查询中的列数?“(”转换后“和“converted2”是可疑的。)

问问自己,“我能减少的行数?”

你所做的一切,考虑partitioning后。

分区之后(或者之前分区)考虑OLAP表进行汇总。