Don*_*tis 6 php doctrine symfony doctrine-orm adodb-php
我有10万多行的表,我想在教义中选择所有这些,并在每行中执行一些操作,在symfony2中使用doctrine我尝试使用此查询:
$query = $this->getDefaultEntityManager()
->getRepository('AppBundle:Contractor')
->createQueryBuilder('c')
->getQuery()->iterate();
foreach ($query as $contractor) {
// doing something
}
Run Code Online (Sandbox Code Playgroud)
但后来我得到内存泄漏,因为我认为它在内存中写入了所有数据.
当我这样做时,我在ADOdb中有更多的经验,在那个库中:
$result = $ADOdbObject->Execute('SELECT * FROM contractors');
while ($arrRow = $result->fetchRow()) {
// do some action
}
Run Code Online (Sandbox Code Playgroud)
我没有任何内存泄漏.
那么如何从表中选择所有数据并且不会在symfony2中使用doctrine获取内存泄漏?
问题编辑
当我尝试删除foreach并且只是迭代时,我也会遇到内存泄漏:
$query = $this->getDefaultEntityManager()
->getRepository('AppBundle:Contractor')
->createQueryBuilder('c')
->getQuery()->iterate();
Run Code Online (Sandbox Code Playgroud)
通常的方法是使用iterate().
$q = $this->getDefaultEntityManager()->createQuery('select u from AppBundle:Contractor c');
$iterableResult = $q->iterate();
foreach ($iterableResult as $row) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
但是,正如学说文档所说,这仍然可能导致错误.
结果可以由数据库客户端/连接完全缓冲,分配PHP进程不可见的额外内存.对于大型集合,这可能很容易因为没有任何理由而终止该过程.
最简单的方法是简单地创建具有偏移和限制的较小查询.
//get the count of the whole query first
$qb = $this->getDefaultEntityManager();
$qb->select('COUNT(u)')->from('AppBundle:Contractor', 'c');
$count = $qb->getQuery()->getSingleScalarResult();
//lets say we go in steps of 1000 to have no memory leak
$limit = 1000;
$offset = 0;
//loop every 1000 > create a query > loop the result > repeat
while ($offset < $count){
$qb->select('u')
->from('AppBundle:Contractor', 'c')
->setMaxResults($limit)
->setFirstResult($offset);
$result = $qb->getQuery()->getResult();
foreach ($result as $contractor) {
// do something
}
$offset += $limit;
}
Run Code Online (Sandbox Code Playgroud)
使用这些繁重的数据集,这很可能会超过最长执行时间,默认情况下为30秒.因此,请确保在php.ini中手动更改set_time_limit.如果您只想更新具有已知模式的所有数据集,则应考虑编写一个大的更新查询,而不是在PHP中循环和编辑结果.
归档时间: |
|
查看次数: |
9817 次 |
最近记录: |