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

时间:2018-02-08 09:58:32

标签: php mysql yii2

我正在使用Yii2开发仪表板。数据保存在远程SQL服务器数据库中,我将其复制到本地MySQL数据库中。通过添加新行不断更新数据。我需要每天至少更新一次本地版本。目前相关表中大约有150万行,每行通过每行不包含太多数据。

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

我的方法是每24小时获取远程表的完整副本。问题是当我这样做时PHP运行内存不足。我找到了Yii2 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. 如果上述方法不起作用,我应该如何使用?

1 个答案:

答案 0 :(得分:0)

您需要使用

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

的主要原因
  

注意:这将在默认安装时始终发生   PHP7现在由于mysqlnd现在如何通过添加结果集而起作用   进程自身的内存使用情况:   http://php.net/manual/en/mysqlinfo.concepts.buffering.php

     

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

     

mysqlnd现在推荐使用PDO libmysqlclient扩展程序   <ManagementPack xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ContentReadable="true"> <Manifest> <Identity> <ID>CloudMonix.ResourceMonitoring</ID> <Version>1.0.0.0</Version> </Identity> <Name>CloudMonix Resource Monitoring Pack</Name> <References> <Reference Alias="System"> <ID>System.Library</ID> <Version>7.5.8501.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> <Reference Alias="SystemCenter"> <ID>Microsoft.SystemCenter.Library</ID> <Version>7.0.8437.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> </References> </Manifest> <TypeDefinitions> <EntityTypes> <ClassTypes> <ClassType ID="CloudMonix.ResourceMonitoring.Resource" Accessibility="Public" Abstract="false" Base="System!System.Entity" Hosted="false" Singleton="false"> <Property ID="ResourceId" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="1" /> <Property ID="ResourceType" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="1" /> <Property ID="ResourceStatus" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="1" /> <Property ID="ResourceGroups" Type="string" Key="false" CaseSensitive="false" Length="1024" MinLength="1" /> </ClassType> </ClassTypes> </EntityTypes> </TypeDefinitions> <Presentation> <Views> <View ID="CloudMonix.ResourceMonitoring.MainView" Accessibility="Public" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" TypeID="SystemCenter!Microsoft.SystemCenter.StateViewType" Visible="true"> <Category>Operations</Category> <Criteria> <InMaintenanceMode>false</InMaintenanceMode> </Criteria> <Presentation> <ColumnInfo Index="0" SortIndex="0" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Descending"> <Name>State</Name> <Id>CloudMonix.ResourceMonitoring.Resource</Id> </ColumnInfo> <ColumnInfo Index="1" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending"> <Name>Resource Type</Name> <Id>ResourceType</Id> </ColumnInfo> <ColumnInfo Index="2" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending"> <Name>Resource Name</Name> <Id>DisplayName</Id> </ColumnInfo> <ColumnInfo Index="3" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending"> <Name>Resource Status</Name> <Id>ResourceStatus</Id> </ColumnInfo> <ColumnInfo Index="4" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending"> <Name>Resource Groups</Name> <Id>ResourceGroups</Id> </ColumnInfo> </Presentation> <Target /> </View> </Views> <Folders> <Folder ID="CloudMonix.ResourceMonitoring.MainFolder" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" /> </Folders> <FolderItems> <FolderItem ElementID="CloudMonix.ResourceMonitoring.MainView" Folder="CloudMonix.ResourceMonitoring.MainFolder" /> </FolderItems> </Presentation> <LanguagePacks> <LanguagePack ID="ENU" IsDefault="false"> <DisplayStrings> <DisplayString ElementID="CloudMonix.ResourceMonitoring"> <Name>CloudMonix Resource Monitoring</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.MainFolder"> <Name>CloudMonix Folder</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.MainView"> <Name>CloudMonix Resource View</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource"> <Name>CloudMonix Resource</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceId"> <Name>Resource Id</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceType"> <Name>Resource Type</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceStatus"> <Name>Resource Status</Name> <Description></Description> </DisplayString> <DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceGroups"> <Name>Resource Groups</Name> <Description></Description> </DisplayString> </DisplayStrings> </LanguagePack> </LanguagePacks> </ManagementPack> 现在“不推荐”

比上面提供的解决方法更好的替代方法是使用与IHIPOP@Github提供的功能无关的数据库连接,详情请参阅完整ISSUE