我们在运行时遇到了奇怪的性能问题
- PHP 5.5.18-1上的Zend Framework 2.3.3
- Doctrine MongoDB ODM模块(https://github.com/doctrine/mongodb,https://github.com/doctrine/DoctrineMongoODMModule)
- Ubuntu 12.04上的VirtualBox通过Vagrant(https://vagrantcloud.com/hashicorp/boxes/precise64)
我们确信这是一个而不是数据库问题(在一个真实的MongoDB实例中尝试过,结果仍然相同)。
场景
我们已经定义了以类似于以下方式与条令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
在查看了XDebug数据的一些屏幕截图后,我认为您只是以错误的方式使用了ORM/ODM,因为您正在批量处理>13K的结果。
有关此类操作的正确解决方案,请参阅http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html
发生的事情很简单:-ODM从数据库加载一条记录-ODM将该记录存储到CCD_ 1中-在flush中,ODM迭代UnitOfWork
中的所有条目,查找更改的文档/实体
如果在UnitOfWork
中继续存储更多的数据,那么很明显,每次重复操作时迭代将花费更长的时间。
您应该在正在处理的批块之间调用ObjectManager#clear()
。
所以这不是一个答案,我将寻求建议。在本地机器上运行速度较慢是正常的,更不用说在虚拟机器上了。
可能有帮助的事情:
- 您可以通过将其添加到流浪文件中,使虚拟机具有更多内存
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", "1024"]
end
- 还可以使用zf2模块ZendDeveloperTools,它将显示您的请求、分组、数据库查询(它与条令一起工作)的时间以及不需要的时间。你可以精确定位任何运行缓慢的东西
只是一个旁注。为什么在12.04上运行php5.5,为什么不在14.04上运行(它更可靠,但不那么精确)。设置起来更容易。