[英]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
}
所以我想我有两个问题-
batch()函数是否正确使用?
如果以上方法无效,应该如何使用?
您需要使用
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.