繁体   English   中英

使用Yii2将大型数据集导入MySQL

[英]Importing a large dataset into MySQL using Yii2

我正在使用Yii2开发仪表板。 数据保存在远程SQL Server数据库中,我正在将其复制到本地MySQL数据库中。 数据会随着添加新行而不断更新。 我需要每天至少更新一次本地版本。 当前,相关表中的每一行中大约有150万行,每行包含的数据并不多。

短期而言,我无法控制远程表的结构。 它没有主键集,行也没有时间戳,所以(我认为)我无法在每次更新时知道哪些行是新行,哪些行已经存在。

我的方法是每24小时获取远程表的完整副本。 问题是当我这样做时,PHP用完了内存。 我发现了Yii2 yii yii\\db\\Query->batch()函数( http://www.yiiframework.com/doc-2.0/yii-db-query.html#batch()-detail )看起来应该这样做这项工作,但我不确定如何使用它,到目前为止,当我尝试过时,它也会耗尽内存。

到目前为止,我得到的是这样的-

foreach ($query->batch(1000) as $rows) {
    do some stuff
}

所以我想我有两个问题-

  1. batch()函数是否正确使用?

  2. 如果以上方法无效,应该如何使用?

您需要使用

Yii::$app->db->pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,false)

在查询之前,然后启动批处理,您可以将setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false)用于batch()然后在其他情况下将属性返回true

根据DOCS

当处理大量数据时,[[yii \\ db \\ Query :: all()]]之类的方法不合适,因为它们需要将整个查询结果加载到客户端的内存中。 为了解决这个问题,Yii提供了批量查询支持。 服务器保留查询结果,而客户端使用游标一次遍历一批结果。

来自GITHUB

需要注意的是:由于mysqlnd现在通过将结果集的内存使用添加到进程自己的内存中,这将在默认安装的PHP7上一直发生: http : //php.net/manual/en/mysqlinfo.concepts .buffering.php

当使用libmysqlclient作为库时,除非将数据提取到PHP变量中,否则PHP的内存限制不会计算结果集使用的内存。 使用mysqlnd ,所占内存将包括完整的结果集。

mysqlnd是现在推荐的PDO扩展库,而libmysqlclient现在“不推荐”

与上面提供的解决方法相比,更好的替代方法是使用IHIPOP@Github提供的功能中的数据库无缓冲连接,有关详细信息,请参见此处的完整ISSUE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM