我应该从foreach循环中写入db_select(),以便减少性能问题?

时间:2016-10-07 05:36:11

标签: php mysql performance optimization drupal

我一直致力于drupal中的性能改进,因为我想删除db_select()查询,该查询位于foreach循环内以提高性能。 我在这里添加我的代码

foreach( $order->commerce_line_items['und'] as $line_item ) {
      $line_item = commerce_line_item_load($line_item['line_item_id']);
      $product = commerce_product_load($line_item->commerce_product['und'][0]  ['product_id']);
      $stock = $product->commerce_stock['und'][0]['value'];

      $query = db_select('commerce_order', 'c');
      $query->join('commerce_line_item', 'l', 'c.order_id = l.order_id');
      $query->addExpression('SUM(quantity)', 'quantity');
      $query->condition('l.line_item_label', $product->sku, '=');
      $query->condition('c.status', 'completed', '<>');
      $result = $query->execute()->fetchAssoc();
      $quantity = $result['quantity'];
      if ( ($stock > 0) && ($quantity > $stock) ) {
        $num_updated = db_update('commerce_order')
                       ->fields(array(
                        'status' => 'manufacturer'
                       ))
                       ->condition('order_id', arg(1), '=')
                       ->execute();
      }
    }

1 个答案:

答案 0 :(得分:0)

您可以在循环中对数据库进行多次查询,可以移动。

commerce_ENTITY_TYPE_load的每次调用都是数据库访问。您应该使用commerce_ENTITY_TYPE_load_multiple功能。这意味着收集数组中所有需要的对象,由它们各自的ID索引,这需要一些基本的锅炉板代码。

// Collect line item IDs (indexed by delta);
$line_item_ids = array_map(function ($line_item) {
  return $line_item['line_item_id'];
}, field_get_items('commerce_order', $oder, 'commerce_line_items'));
// Get line items, indexed by IDs.
$line_items = commerce_line_items_load_multiple($line_item_ids);

// Collect product IDs, indexed by line item IDs.
$product_ids = array_map(function ($line_item) {
  return field_get_items('commerce_line_item', $line_item, 'commerce_product')[0]['product_id'];
}, $line_items);
// Get products, indexed by IDs.
$products = commerce_product_load_multiple($product_ids);

自定义选择查询用于检索与订单项的产品的SKU匹配的订单项的数量。并且您已将所有订单项和产品加载为实体。因此不需要更多的数据库查询和SKU的使用。此外,由于查询会在订单数量为&gt;的订单项后自动更新订单。找到股票,你可以打破第一个项目的循环。

foreach ($line_items as $line_item_id => $line_item) {
  $product = $products[$products_ids[$line_item_id]];
  $stock = field_get_items('commerce_product', $product, 'commerce_stock')[0]['value'];
  $quantity = $line_item->quantity;
  if (($stock > 0) && ($quantity > $stock)) {
    $num_updated = db_update('commerce_order')
      ->fields(array(
        'status' => 'manufacturer'
      ))
      ->condition('order_id', $order->order_id)
      ->execute();
    break;
  }
}