我一直致力于drupal的性能改进,因为我想删除foreach循环内的db_select()查询以提高性能。这里我添加了我的代码
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();
}
}
在循环中有多个对DB的查询可以移动。
每次对commerce_ENTITY_TYPE_load
的调用都是一次DB访问。您应该使用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。此外,由于查询在找到quantity> stock的行项目后更新订单本身,因此可以为第一个找到quantity> stock的项目打破循环。
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;
}
}