Laravel帮助优化命令脚本

时间:2019-11-22 14:44:06

标签: laravel optimization

我正在使用Lumen框架v5.8(与Laravel相同)

我有一个命令,用于读取大XML(400Mo)并从此文件中的数据更新数据库中的数据,这是我的代码:

public function handle()
{
    $reader = new XMLReader();
    $reader->open(storage_path('app/mesh2019.xml'));

    while ($reader->read()) {
        switch ($reader->nodeType) {
            case (XMLREADER::ELEMENT):
                if ($reader->localName === 'DescriptorRecord') {
                    $node = new SimpleXMLElement($reader->readOuterXML());
                    $meshId = $node->DescriptorUI;
                    $name = (string) $node->DescriptorName->String;

                    $conditionId = Condition::where('mesh_id', $meshId)->first();

                    if ($conditionId) {
                        ConditionTranslation::where(['condition_id' => $conditionId->id, 'locale' => 'fr'])->update(['name' => $name]);
                        $this->info(memory_get_usage());
                    }
                }
        }
    }
}

因此,我必须在XML中找到每个DescriptorUI元素,该值对应于我的类mesh_id的{​​{1}}属性。

因此,通过Condition我得到了Condition对象。

之后,我需要更新$conditionId = Condition::where('mesh_id', $meshId)->first(); => Condition的子级。因此,我只获取元素ConditionTranslation并更新DescriptorName的{​​{1}}字段

在脚本结尾处,您会看到name,当我运行命令时,该值每次都会增加,直到脚本运行得非常慢...再也不会结束。

如何优化此脚本?

谢谢!

编辑:Laravel有没有一种方法可以预更新多个对象,最后只保存一次所有对象?就像Symfony的ConditionTranslation方法

1 个答案:

答案 0 :(得分:0)

ON DUPLICATE KEY UPDATE

的解决方案
public function handle()
    {
        $reader = new XMLReader();
        $reader->open(storage_path('app/mesh2019.xml'));

        $keyValues = [];
        while ($reader->read()) {
            switch ($reader->nodeType) {
                case (XMLREADER::ELEMENT):
                    if ($reader->localName === 'DescriptorRecord') {
                        $node = new SimpleXMLElement($reader->readOuterXML());
                        $meshId = $node->DescriptorUI;
                        $name = (string) $node->DescriptorName->String;

                        $conditionId = Condition::where('mesh_id', $meshId)->value('id');

                        if ($conditionId) {
                            $keyValues[] = "($conditionId, '".str_replace("'","\'",$name)."')";
                        }
                    }
            }
        }
        if (count($keyValues)) {
            \DB::query('INSERT into `conditions` (id, name) VALUES '.implode(', ', $keyValues).' ON DUPLICATE KEY UPDATE name = VALUES(name)');
        }
    }