Yii2 数据库批量处理技巧


数据库批量处理技巧


正文

查询

数据大批量查询时,要考虑内存溢出,如果上万条查询,理论上需要降低到百条量级。 还有就是列表数据只获取自己需要的字段,结果使用asArray()返回,而不要封装成对象返回。

下面分条说一下可用的方法。

例如我们用下面结构的表:

CREATE TABLE `record` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL COMMENT '标题',
  `content` varchar(2000) NOT NULL COMMENT '内容',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='记录表'

limit方式

$offset = 110;
$lists = Record::find()
    ->limit(100)
    ->offset($offset)
    ->asArray()
    ->all();

batch方式

batch指定条数,每次只拿这么多,循环执行,默认值100。

$query = new yii\db\Query();
$query->from('record');
foreach($query->batch() as $records){
    foreach($records as $record){
        echo $record['title'];
        echo "<br/>>";
    }
}

或者

$lists = Record::find()->asArray();
foreach($lists->batch() as $records){
    foreach($records as $record){
        echo $record['title'];
        echo "<br/>>";
    }
}

为什么 batch() 方法可以节省内存呢?因为 foreach 循环的是对象,有自己的循环方式,与数组不一样。

参考 «https://www.jb51.net/article/210214.htm» https://www.yiichina.com/code/1955

each方式

$query = new yii\db\Query();
$query->from('record');
foreach($query->each() as $record){
    echo $record['title'];
    echo "<br/>>";
}

实现分析

查询构造器里面实例化BatchQueryResult类代码如下:

public function batch($batchSize = 100, $db = null)
{
    return Yii::createObject([
        'class' => BatchQueryResult::className(),
        'query' => $this,
        'batchSize' => $batchSize,
        'db' => $db,
        'each' => false,
    ]);
}

public function each($batchSize = 100, $db = null)
{
    return Yii::createObject([
        'class' => BatchQueryResult::className(),
        'query' => $this,
        'batchSize' => $batchSize,
        'db' => $db,
        'each' => true,
    ]);
}

写入

使用batchInsert() 一条一条循环执行插入。

$table_name = "record";

$columns = ["title", "content"];

$rows = [
    [“标题1”,  “内容1”],
    [“标题2”,  “内容2”],
    [“标题3”,  “内容3”],
    [“标题4”,  “内容4”],
];

$num = Yii::$app->db->createCommand()->batchInsert($table_name, $columns, $rows)->execute();






参考资料

yii2 batch和each的区别是什么 https://www.php.cn/phpkj/yii/437974.html

据大批量查询时,要考虑内存溢出,如果上万条查询,理论 https://www.yiichina.com/code/1955

数据库访问对象(Database Access Objects) https://www.yiichina.com/doc/guide/2.0/db-dao

yii2 batchInsert批量插入 https://blog.csdn.net/mengzuchao/article/details/80186420

php中foreach遍历类对象的总结 https://www.jb51.net/article/210214.htm


返回