从大表处理统计数据

时间:2014-11-19 16:42:03

标签: php mysql bigdata

我有一个广告网站,我正在努力寻找最有效的方法来处理统计数据。我的目标是每天显示唯一身份访问者和点击次数。

这就是它的工作原理:发布商可以添加网站,然后向其添加无限的广告空间,这样他们就可以在同一页面或不同页面上运行多个横幅。

WEBSITES
id | url

ADSPACES
id | website_id | info

VIEWS
id | adspace_id | ip | date (YYYY-MM-DD)

ADSPACES_STATS
id | adspace_id | views | date (YYYY-MM-DD)

WEBSITES_STATS
id | website_id | views | date (YYYY-MM-DD)

更新广告空间的观看次数和点击次数的脚本已经完成:

$getViewsByAdspace = $db->query('SELECT count(*) as views, adspace FROM views WHERE date="'.date('Y-m-d').'" GROUP BY adspace ORDER BY id ASC');
while($getViewsForAdspace = $getViewsByAdspace->fetch(PDO::FETCH_ASSOC))
{
    $adspaceId = $getViewsForAdspace['adspace'];
    $adspaceViews = $getViewsForAdspace['views'];

    if( $db->query('UPDATE adspace_stats SET views='.$adspaceViews.' WHERE adspace='.$adspaceId.' AND date="'.date('Y-m-d').'"')->rowCount() == 0 )
        $db->exec('INSERT IGNORE INTO adspace_stats (adspace, date, views, clicks) VALUES ('.$adspaceId.', "'.date('Y-m-d').'", '.$adspaceViews.', 0)');
}

脚本每小时运行一次。

现在我需要一个脚本来更新网站的统计信息。我无法找到一种有效的方法,上面的脚本大约需要20秒,表格包含10M条目,这是完美的。

我看到的唯一方法是:

获取属于某个网站的所有广告空间,然后按以下方式进行查询:SELECT COUNT(DISTINCT ip) as views FROM views WHERE (adspace=x OR adspace=Y ...) AND date=today

1 个答案:

答案 0 :(得分:0)

很糟糕但是有效。

$websites = $db->query('SELECT * FROM websites WHERE state=0 ORDER BY id ASC');
while($website = $websites->fetch(PDO::FETCH_ASSOC))
{
    $query='';
    $getAdspacesByWebsite = $db->query('SELECT * FROM adspaces WHERE state=1 AND website='.$website['id'].' ORDER BY id ASC');
    while($adspace = $getAdspacesByWebsite->fetch(PDO::FETCH_ASSOC))
    {
        $query.='OR adspace="'.$adspace['uniqid'].'" ';
    }
    if( $query!='' ) {
        $query = 'SELECT count(DISTINCT ip) as views FROM views WHERE date="' . date('Y-m-d') . '" AND (' . substr($query, 3) . ') ORDER BY id ASC';

        $result = $db->query($query)->fetch(PDO::FETCH_ASSOC);

        if( $db->query('UPDATE websites_stats SET views='.$result['views'].' WHERE website='.$website['id'].' AND date="'.date('Y-m-d').'"')->rowCount() == 0 )
            $db->exec('INSERT IGNORE INTO websites_stats (website, date, views, clicks) VALUES ('.$website['id'].', "'.date('Y-m-d').'", '.$result['views'].', 0)');
    }
}