【问题标题】:Process stats from big table来自大表的进程统计信息
【发布时间】:2014-11-20 02:42:13
【问题描述】:

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

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

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

【问题讨论】:

  • 您正在使用 PDO,这很棒,但请务必使用 prepared statements。由于您鲁莽地使用字符串连接,因此您在这里得到的可能充满了SQL injection bugs
  • @tadman 这可能是一个 cron 工作,sql 注入从哪里来?
  • @Marius.C 当你假设一切正常时,你就会遇到麻烦。第一次就做好,以后就不会有问题了。
  • 没错。同意。
  • @tadman 这不会显着减慢执行时间吗?

标签: php mysql bigdata


【解决方案1】:

这很糟糕,但它有效。

$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)');
    }
}

【讨论】:

    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    相关资源
    最近更新 更多