$bean-save() 在 Sugarcrm 中每条记录花费的时间太长

$bean-save() is taking way too long per record in Sugarcrm

我有一个函数可以重新计算给定模块中计算字段的值。 这适用于具有少量记录的小模块。 但是,当我在联系人或帐户等更大的模块上尝试此操作时,保存每条记录最多需要三秒钟。

超过 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(); 花费的时间太长了。

有什么方法可以加快速度吗?

首先,我建议使用您选择的工具找出保存的哪一部分需要这么长时间... profiler/debugger/custom Timers/etc.

  • 是钩子吗?如果重新计算不需要,请对其进行优化或制作自定义标志以跳过它。
  • 是查询吗?分析查询 (EXPLAIN) 以了解向数据库添加索引是否有帮助。
  • 是否日志输出过多?减少它。
  • 是相关bean计算的bean加载吗?优化公式或在不需要时跳过。

您可以尝试的其他事情:

  • 使用查询预过滤要重新保存的 bean(例如,如果处于特定状态或在特定相关 bean 之后修改等,则可能不需要重新计算记录?)。
  • 触发更新代码中的计算字段并检查 bean 的(相关)值之后是否实际更改,如果没有,则无需重新保存它,您可以跳到下一条记录。
  • 如果这只是关于更新不相关的计算字段,即使存在相关的计算字段,那么您可以决定(暂时?)将 $sugar_config['disable_related_calc_fields'] 设置为 true。这样 Sugar 就不必加载那些相关的 bean。

如果没有希望了:

  • 并行考虑 运行 这些任务
  • 使用 SQL/SugarQuery 重写您需要更新的任何内容(可能无法实现,具体取决于复杂性和含义)。

备注:

  • 请注意,至少从 Sugar 7.7 开始,get_full_list() 已被弃用,取而代之的是 SugarQuery 和 $bean->fetchFromQuery()。但是,我建议使用查询仅检索 IDs 并使用 BeanFactory::retrieveBean($module, $id) 加载 bean,可能在计算后分别关闭它们,使用 BeanFactory::unregisterBean($bean); unset($bean); 来帮助垃圾收集器保持低内存配置文件。
    我过去也确实使用过 get_full_list()fetchFromQuery,但由于使用这种方式时 bean 没有完全加载,所以出现了灾难性的副作用而不是 BeanFactory。
    所有记录因此丢失了他们的电子邮件地址(!)。我不高兴。
  • Sugar 8:特别是如果您有很多联系人,table erased_fields 上的错误默认索引会在其中只有一条记录时大大降低速度。 erased_fields 默认情况下只有一个 2 列索引(虽然在重要查询中不使用),因此您必须为这 2 列添加 2 个单独的索引,并且事情将是 很多又快了。