折半插入_统计广告访问

折半插入_统计广告访问

最近在做广告访问统计。场景:打印广告,发放,用户访问后,需要对访问进行统计。mailno不是索引,但是created是创建的时间,而且考虑到只有最近一段的时间会访问,时间长了,历史数据应该没有人访问。如果不用mailno索引的时候,插入比较慢。所以,想到了折半插入的方式。

代码

代码如下:

$ip = ClientService::getIP();
//过滤引号
$other = \addslashes(ClientService::agent());
$queryDate = date('Y-m-d',strtotime("-5 day"));
//mailno 不是索引,可能执行时间很长,改进为:利于create索引,折半插入。
//%s  取值>|<=
$sql = "UPDATE yc_advert_records FORCE INDEX(created) SET visit_count = visit_count + 1 ,visited = '$now',visited_ip = '$ip',other = '$other' where created %s '$queryDate' and mailno=$mailno";
try{
    $count = $pdo->exec(\sprintf($sql,'>'));//$count int  受影响数。
    //如果未更新,则在另外一半中进行操作。
    if(!$count){
        $count = $pdo->exec(\sprintf($sql,'<='));
    }
} catch(\Exception $e){
    $msg = $e->getMessage() . "\r\n[SQL]$sql";
    DingService::send($msg);
}

但是上面的代码提升不是特别明显。

大概看了一下,说是:

不用created折半插入的时候,

此时用的是主键id索引。

而用created折半插入的时候,

此时用的是created索引。

sql对比

正常查询

时间3.6秒

UPDATE yc_advert_records SET visit_count = visit_count + 1 ,visited = '2020-08-18 12:54:54',visited_ip = '127.0.0.1',other = '1111' where mailno=4305185704781

1597734509001

1597734655168

折半查询

时间4.4秒

UPDATE yc_advert_records SET visit_count = visit_count + 1 ,visited = '2020-08-18 12:54:54',visited_ip = '127.0.0.1',other = '1111' where created > '2020-08-13' and mailno=4305185704781

1597734743276

1597734608762

强制用索引(折半查询)

增加FORCE INDEX(created),然后时间上立马变化了。真是峰回路转。

UPDATE yc_advert_records FORCE INDEX(created) SET visit_count = visit_count + 1 ,visited = '2020-08-18 12:54:54',visited_ip = '127.0.0.1',other = '1111' where created > '2020-08-13' and mailno=4305185704781

1597735105508

1597735140529

最终方案

虽然上面折腾了很久,也终于利于上了其他索引,折腾查询,提升了性能。但是,直接增加mailno索引他不香吗?所以,直接利用索引,最终查询任何的速度都很快。代码回退,简单增加索引解决。