1

我们在运行时遇到了奇怪的性能问题:

我们确定这不是数据库问题(用真正的 MongoDB 实例尝试过,结果仍然相同)。


设想

我们以类似于以下的方式定义了与 Doctrine ODM 一起使用的对象:

<?php

namespace CatalogueManager\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\Common\Collections\ArrayCollection;

/*
 * @ODM\Document(repositoryClass="CatalogueManager\Repository\ProductRepository")
 */
class Item
{
    /** @ODM\Id */
    protected $id;

    /** @ODM\String */
    protected $name;

    /** @ODM\Timestamp */
    protected $created;

    /** @ODM\Timestamp */
    protected $updated;

    // ---------------------------------------------------------------------- //

    /**
     * Return properties as an array. Helper method to assist with converting
     * doctrine objects to arrays so we can return front-end api calls as json.
     *
     * Required as currently Doctrine ODM do not support array hydration of
     * referenced documents.
     *
     * @access public
     * @return array
     *
     */
    public function toArray()
    {
        $arr = ['id'          => $this->id,
                'name'        => $this->name,
                'urlSlug'     => $this->urlSlug,
                'desc'        => $this->desc,
                'metaData'    => $this->metadata,
                'category'    => $this->category,
                'brand'       => $this->brand,
                'assets'      => $this->assets,
                'shipping'    => $this->shipping,
                'specs'       => $this->specs,
                'attrs'       => $this->attrs,
                'optionTypes' => $this->optionTypes
                ];

        return $arr;
    }

    // ---------------------------------------------------------------------- //

    /**
     * Getter
     *
     * @access public
     * @return string
     *
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Getter
     *
     * @access public
     * @return string
     *
     */
    public function getName()
    {
        return $this->name;
    }

    // ---------------------------------------------------------------------- //

    /**
     * Setter
     *
     * @param string $value Property value
     *
     * @access public
     * @return void
     *
     */
    public function setName($value)
    {
        $this->name = $value;
    }

}

我们使用这些来导入大约。100 个产品进入产品数据库。这一切在真机上大约需要 5 秒,但在虚拟机上尝试时,大约需要。25秒做同样的事情。

看起来问题可能是Apache在处理这一切的过程中占用了99% 的负载,但我很难确定到底发生了什么。

任何形式的建议将不胜感激......


更新

这似乎只在写入数据时发生。读取数据似乎没问题。

Webgrind 数据(截图)可用:https ://www.dropbox.com/s/jjlg7ano6epy6t1/webgrind.png?dl=0

4

2 回答 2

2

在查看了一些 XDebug 数据的屏幕截图后,我认为您只是以错误的方式使用 ORM/ODM,因为您正在批处理 > 13K 结果。

此类操作的正确解决方案在http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html进行了说明

发生的事情非常简单: - ODM 从 DB 加载一条记录 - ODM 将该记录存储到UnitOfWork - 在刷新时,ODM 遍历 中的所有条目UnitOfWork,查找更改的文档/实体

如果您继续在 中存储更多数据UnitOfWork,那么显然每次重复操作时迭代将花费更长的时间。

您应该ObjectManager#clear()在正在处理的批处理块之间调用。

于 2014-11-12T13:32:11.767 回答
1

所以这不会是一个答案,我会寻求建议。在本地机器上运行速度较慢是正常的,更不用说在虚拟机器上。

可能会有所帮助的事情:

  1. 您可以通过将其添加到您的 vagrant 文件来使您的虚拟机拥有更多内存

config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", "1024"] end

  1. 还可以使用 zf2 模块ZendDeveloperTools,它将向您显示您的请求、路由、数据库查询(它适用于学说)以及不占用的时间。您可以查明运行缓慢的任何内容。

只是一个旁注。你为什么在 12.04 上运行 php 5.5,为什么不是 14.04(它更可靠,但不那么精确)。设置起来更容易。

于 2014-11-11T17:53:52.940 回答