上上个月公司后台需要写一个优惠券管理的功能,其中涉及到根据手动输入用户ID来发放和通过小区来筛选符合条件的用户发放等情况。当用户数不是很多,比如就20个左右时,将用户记录保存到MySQL还不觉得有什么问题。可是根据用户类型或小区等筛选时,一个小区可能有超过一万个的用户,很容易超时造成偏后的用户来不及保存就连接中断了。
后来受指点使用Yii2提供的对象方法,批量导入一万多条的数据也是秒完成。毕竟当时涉及到需要给发放优惠券的用户发送一条私信通知,这个连接非常耗时,没办法同步发送,最后只能拆分开来,将用户存入redis中,用系统自带的crontab计划任务来完成了。
public static function generateCoupon($userIds, $args)
{
$now = time();
$count = count($userIds);
if (! $count) {
return false;
}
$i = 0;
while ($i < $count) {
$values = [];
for ($j = 0; $j < 500; $j++) {
if ($i + $j >= $count) {
$j = 501;
} else {
$values[] = [
$args['sendid'],
$args['couponid'],
$args['handler'],
$userIds[$i + $j],
$now,
$now,
];
}
}
if (empty($values)) {
return true;
}
//确定连接的数据库名和表名
@ \common\models\shop\CouponIndex::getDb()->createCommand()->batchInsert(\common\models\shop\CouponIndex::tableName(), [
'sendid',
'couponid',
'handler',
'userid',
'ctime',
'utime',
], $values)->execute();
$i += 500;
}
return true;
}