针对几千条以上的数组,如何循环呢?

2017-03-12 20:01:57 +08:00
 MrMike

我需要循环这个大数组(web 的方式),然后组合成一个字符串,再在循环外进行数据的插入工作。但是现在循环超过 5000 条时,页面就不动了,内存都用完了。有没有好的建议和解决方案,如何处理这种大数组的循环呢?

3831 次点击
所在节点    PHP
30 条回复
qiayue
2017-03-12 20:09:55 +08:00
是否可以把数组放到数据库里,每次取出一些来处理呢?
forelegance
2017-03-12 20:17:17 +08:00
需要一下子都读取完,可以每读 3000 条缓存一下当前的 sumary 再继续,关键组成一个字符串显示出来???? 不会有人这么弄的吧
MrMike
2017-03-12 20:17:20 +08:00
@qiayue 我就是要把数组里的数据插入到数据库的。。。
forelegance
2017-03-12 20:17:50 +08:00
你是读取基因组或者转录组数据嘛???
MrMike
2017-03-12 20:21:49 +08:00
@forelegance 咋个缓存?我就是想这样,固定循环多条数据,循环一部分,然后再将余下的数组生成一个新的数组再循环,但是现在还是要死掉。
loading
2017-03-12 20:25:24 +08:00
是在浏览器跑吗?你的应该是运算量太大,页面受影响了,看看 worker 。
随便找的一个:
http://www.cnblogs.com/feng_013/archive/2011/09/20/2175007.html
Ouyangan
2017-03-12 21:26:53 +08:00
换个思路 , 能不能提交文件,让后端来处理数据呢
iyaozhen
2017-03-12 22:23:59 +08:00
5000 多条也很快吧。先考虑优化一下循环。和数据库插入。话说代码呢?

或者异步处理,用户提交数据后马上返回成功(ob_end_flush),然后 PHP-fpm 其实还在运行。还比较耗时的话做成任务队列
AbrahamGreyson
2017-03-12 22:30:05 +08:00
通常这种需求要实现生成器,也就是 yeild

自己看吧

http://php.net/manual/zh/language.generators.overview.php
usedname
2017-03-12 22:38:58 +08:00
使用 yield ,同 9 楼
MrMike
2017-03-12 22:56:58 +08:00
@iyaozhen 代码这里:
代码:
$total = count($importData);
$page = intval(ceil($total / $pageNumber));
for ($p = 0; $p < $page; $p++)
{
$start = $p * $pageNumber;
$sliceData = array_slice($importData, $start, $pageNumber, true);
$productSQLValue = false;
foreach ($sliceData as $fieldValue)
{
dump($fieldValue);
// if (!$fieldValue['modelName'] || !$fieldValue['type'] || !$fieldValue['category'])
// continue;
// $categoryID = $this->getProductCategoryID($fieldValue['category']);
// $typeID = $this->getProductTypeID($fieldValue['type']);
// if (!$categoryID || !$typeID)
// continue;
// $model = $this->getModel($fieldValue['brandName'], $fieldValue['modelName']);
// $resourceModel = $model['resourceModel'];
// if ($resourceModel)
// {
// $resourceModel = $resourceModel->getId();
// }
// $product = $this->entityManager->getRepository('DemoProductBundle:Product')->findOneBy(array('creator' => $productCreator, 'model' => $model['productModel']));
// $row = array();
// if ($product)
// {
// $row['id'] = $product->getId();
// $row['sn'] = $product->getSn();
// $row['created'] = $product->getCreated()->format('Y-m-d H:i:s');
// } else {
// $row['id'] = $latestProductID + $pID;
// $row['sn'] = $this->redis->getNumber('product-sku');
// $row['created'] = date('Y-m-d H:i:s');
// $pID++;
// }
// $row['title'] = $fieldValue['title'];
// $row['excerpt'] = $fieldValue['excerpt'];
// $row['description'] = $fieldValue['description'];
// $row['city'] = $this->getProductCityID($fieldValue['originPlace']);
// $row['model'] = $model['productModel']->getId();
// $row['resource_model'] = $resourceModel;
// $row['category'] = $categoryID;
// $row['type'] = $typeID;
// $row['retail_price'] = $fieldValue['retailPrice'];
// $row['status'] = 1;
// $row['modified'] = date('Y-m-d H:i:s');
// dump($row);
// $productSQLValue .= "('". implode("','", $row) . "'),";
}
dump($p);
// dump($productSQLValue);
// dump($sliceData);
dump(date('H:i:s'));

// if ($p > 3)
// break;
}

输出 dump($fieldValue);可以工作
// dump($productSQLValue);如果想输出组合后的 sql,就挂掉了。
MrMike
2017-03-12 22:58:24 +08:00
@AbrahamGreyson 之前用过这个,感觉数据不是太多,时间上没有节省多少。现在看来,是循环内,对数据库查询造成的问题了。我已经把代码贴在 11 楼了。
MrMike
2017-03-12 23:00:13 +08:00
@Ouyangan 我想让 cron 来自动执行,但是苦于自己对 shell 脚本不熟,只好暂时不花时间在这个上面了。
fork3rt
2017-03-13 07:51:46 +08:00
你需要 yield
MrMike
2017-03-13 08:55:04 +08:00
@fork3rt 现在貌似问题不是出在循环的问题上了,是我循环里面,需要去查询数据库,我用的是 doctrine 的 ORM 类去读取数据库,速度好像跟原生的 sql 查询有点不一样,不晓得是不是这个原因造成的。
MrMike
2017-03-13 08:55:26 +08:00
@fork3rt 之前用 yield 来测试过的。
harker
2017-03-13 09:24:13 +08:00
数组值作为变量赋值,源数组申请到的内存是不会释放的,而且会成倍叠加申请内存,一步步测试,看看内存从哪里消耗掉的
herozhang
2017-03-13 09:41:40 +08:00
听上去 lz 是在页面上直接 js 来做的吧?调试看下内存分配的情况吧
eoo
2017-03-13 09:41:40 +08:00
使用 yield
MrMike
2017-03-13 09:42:48 +08:00
@herozhang 不是用 js 调用的,直接通过页面提交,然后后台代码执行的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/346901

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX