我有一个函数重新计算给定模块中计算字段的值。这适用于具有少量记录的小模块。但是,当我在联系人或帐户等较大的模块上尝试此操作时,保存每条记录最多需要三秒钟。
超过100,000条记录需要83小时才能处理。
这是我的代码。
$moduleList = array("Accounts", "Quotes");
if (!defined('sugarEntry') || !sugarEntry)
die('Not A Valid Entry Point');
require_once('include/utils.php');
require_once('include/export_utils.php');
foreach( $moduleList as $module) {
print "Updating $module...\n<br>";
$cnt = 0;
$moduleBean = BeanFactory::getBean($module);
$beanList = $moduleBean->get_full_list($order_by,$where);
if( $beanList != null ) {
foreach($beanList as $b) {
// These lines prevent the modified date and user from being changed.
$b->update_date_modified = false;
$b->update_modified_by = false;
$b->tracker_visibility = false;
$b->in_workflow = true;
$b->save();
$cnt++;
}
}
print "Finished updating: $cnt records.\n<br>";
当我记录每个记录所花费的时间时,很明显$b->save();
需要的时间太长。
有什么方法可以加快速度吗?
首先,我建议使用您选择的工具找出保存的哪个部分需要这么长时间...探查器/调试器/自定义计时器/等。
EXPLAIN
)以确定向数据库添加索引是否有帮助。您可以尝试的其他事项:
$sugar_config['disable_related_calc_fields']
设置为true。这样Sugar就不必加载那些相关的bean。如果没有希望了:
笔记:
get_full_list()
至少被弃用,因为至少Sugar 7.7并被SugarQuery和$bean->fetchFromQuery()
取代。但是我建议使用Query只检索ID并使用BeanFactory::retrieveBean($module, $id)
加载bean,可能在计算后逐个解除它们,使用BeanFactory::unregisterBean($bean); unset($bean);
来帮助垃圾收集器保持低内存配置文件。
此外,我过去使用get_full_list()
和fetchFromQuery
带来了灾难性的副作用,因为豆子在使用这种方式而不是BeanFactory时没有完全装满。
因此,所有记录都丢失了他们的电子邮件地址(!)。我不高兴。erased_fields
上的错误的默认索引会在它有一条记录时减慢很多。 erased_fields
默认只有一个2列索引(虽然不在重要的查询中使用),所以你必须为这两列添加2个单独的索引,事情会再快一些。