21. Yii2批量导入大数据的快捷方法

上上个月公司后台需要写一个优惠券管理的功能,其中涉及到根据手动输入用户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;
}