Php 条令查询内存使用
条令似乎占用了超过4MB的RAM来执行一个简单的查询:Php 条令查询内存使用,php,doctrine,memory-management,Php,Doctrine,Memory Management,条令似乎占用了超过4MB的RAM来执行一个简单的查询: print memory_get_peak_usage()." <br>\n"; $q = Doctrine_Query::create() ->from('Directories d') ->where('d.DIRECTORY_ID = ?', 5); $dir = $q->fetchOne(); print $dir['name']." ".$dir['description']."&l
print memory_get_peak_usage()." <br>\n";
$q = Doctrine_Query::create()
->from('Directories d')
->where('d.DIRECTORY_ID = ?', 5);
$dir = $q->fetchOne();
print $dir['name']." ".$dir['description']."<br>\n";
print memory_get_peak_usage()." <br>\n";
/*************** OUTPUT: **************************
6393616
testname testdescription
10999648
/***************************************************/
print memory\u get\u peak\u usage()。“
\n”;
$q=条令查询::创建()
->从('d'目录)
->其中('d.DIRECTORY_ID=?',5);
$dir=$q->fetchOne();
打印$dir['name']。“.$dir['description']。”
\n”;
打印内存获取峰值使用率()。“
\n”;
/***************输出:**************************
6393616
testname testdescription
10999648
/***************************************************/
这是在一个测试数据库上,其中只有很少的数据-我查询的项目不包含除此处显示的数据以外的任何数据
我设置系统的方式是否有潜在的问题,或者这是条令的标准内存使用方式?从我看来,您的代码似乎没有错
作为测试,我设置了一个快速示例,其中有一个非常简单的表(只有四个字段) 以下是相关代码:
var_dump(number_format(memory_get_peak_usage()));
$test = Doctrine::getTable('Test')->find(1);
var_dump(number_format(memory_get_peak_usage()));
这样做时,我有这样的输出:
string '1,316,088' (length=9)
string '2,148,760' (length=9)
考虑到表格非常简单,而且我只提取了一行,对我来说似乎也“很多”——但这与您得到的以及我在其他项目中看到的非常一致:-(
如果您只需要显示数据,而不需要使用数据(即更新/删除/…),解决方案可能是不获取复杂对象,而只获取简单数组:
$test = Doctrine::getTable('Test')->find(1, Doctrine::HYDRATE_ARRAY);
但是,在这种情况下,实际上没有多大区别
只有40KB的差异——好吧,对于更大的对象/更多的线,这可能仍然是一个好主意
在条令手册中,有一个页面名为;也许它可以帮助您,尤其是以下章节:
哦,顺便说一句:我在PHP5.3.0上做了这个测试;也许这会对使用的内存量产生影响…那么,内存的使用是从哪里来的呢?正如Pascal MARTIN指出的,数组水合作用并没有太大的区别,这是合乎逻辑的,因为我们这里只讨论了一些记录 内存消耗来自通过自动加载按需加载的所有类 如果您没有设置APC,那么是的,您的系统设置方式有问题。对于没有操作码缓存(如APC)的大型php库,甚至不要开始测量性能,也不要期望有好的结果。这不仅会加快执行速度,而且会在除fir之外的所有页面负载上减少至少50%的内存使用st one(APC需要首先缓存字节码)
4MB和您的简单示例闻起来真的像没有APC,否则它会真的有点高。我同意romanb的答案-在使用大型libs/框架时,使用操作码缓存是绝对必须的 与操作码缓存相关的示例 我最近在Zend框架中采用了条令使用,并且对内存使用感到好奇——因此像OP一样,我使用与OPs测试类似的标准创建了一个方法,并将其作为一个整体测试运行,以查看ZF+条令的内存使用峰值 我得到了以下结果: 无APC的结果:
10.25 megabytes
RV David
16.5 megabytes
APC的结果:
3 megabytes
RV David
4.25 megabytes
操作码缓存有很大的不同。条令在条令记录、条令收集和条令查询上提供了一个free()函数,它消除了这些对象上的循环引用,将它们释放出来进行垃圾收集。
要稍微减少内存使用,您可以尝试使用以下代码:
- $record->free(true)–将对所有关系执行深度释放,调用free()
- $collection->free()–这将释放所有集合引用
- Doctrine_Manager::connection()->clean()/clear()–清理连接(并删除标识映射项)
- $query->free()
- 您使用的是哪种版本的学说
- 你在用自动装弹机吗
sfConfig::set('sf_debug', false);
注意在条令查询中使用fetchOne()。此函数调用不会在SQL上附加“Limit 1”
如果您只需要从DB获取一条记录,请确保:
$q->limit(1)->fetchOne()
大表上的内存使用率大大降低
您可以看到fetchOne()将首先作为集合从数据库中获取,然后返回第一个元素
public function fetchOne($params = array(), $hydrationMode = null)
{
$collection = $this->execute($params, $hydrationMode);
if (is_scalar($collection)) {
return $collection;
}
if (count($collection) === 0) {
return false;
}
if ($collection instanceof Doctrine_Collection) {
return $collection->getFirst();
} else if (is_array($collection)) {
return array_shift($collection);
}
return false;
}
这让我担心,因为我正在将条令集成到我的框架中。在担心太多之前,你可能想做更多的测试,使用更大的表、更多的数据,以及所有这些——看看内存增加是否是线性的。;;顺便说一句:我在基于Zend framework和Symfony的项目中看到条令的使用,这从来都不是问题……Pascal MARTIN:也许你知道的这些站点没有重载?我想知道是否有任何主要站点正在使用Doctrine。我通常将新项目锁定为16MB的内存限制。除了一个例外,我从来没有用Doctrine耗尽过该限制。此外,当Doctrine被禁用时,会启动大量内部引用变量和单例第一次使用。1.2文档的链接现在可以在这里找到,如果您使用的是条令+symfony,这很好,但如果您只是使用条令,则不会有帮助。同意Ikon的意见,在symfony中使用分析器gobals ram。因此:
sfConfig::set('sf_debug',false)
在建立数据库连接之前,如果您像我一样将大型表转储到csv,那么这将非常有帮助。您可以在frontend_dev.php或
public function fetchOne($params = array(), $hydrationMode = null)
{
$collection = $this->execute($params, $hydrationMode);
if (is_scalar($collection)) {
return $collection;
}
if (count($collection) === 0) {
return false;
}
if ($collection instanceof Doctrine_Collection) {
return $collection->getFirst();
} else if (is_array($collection)) {
return array_shift($collection);
}
return false;
}