如何加速PHP脚本批量导入大量产品至WooCommerce?
加速WooCommerce产品XML导入的优化方案
你的导入速度慢且服务器资源未充分利用,核心问题在于冗余数据库查询、不必要的钩子触发、单条数据处理的低效性,以下是针对性的优化方案:
1. 修正代码中的冗余与错误逻辑
你修改后的代码存在明显的资源浪费:创建产品对象后未保存就获取ID,再重新查询产品对象,这多了一次无意义的数据库查询。直接在同一个对象上完成所有属性设置,一次性保存即可:
// 预获取默认分类ID(移到循环外部,避免重复查询) $uncategorized_term_id = get_option('default_product_cat'); // 循环处理XML中的产品数据 foreach ($xml_products as $item) { // 初始化产品对象 $product = new WC_Product_Simple(); // 设置核心产品属性 $product->set_name($item['titre_produit']); $product->set_description($item['resume']); $product->set_sku($item['sku']); $product->set_regular_price($item['price']); $product->set_height($item['hauteur']); $product->set_width($item['largeur']); $product->set_length($item['longueur']); $product->set_category_ids([$uncategorized_term_id]); // 直接设置分类 // 批量添加自定义元数据(避免多次调用add_meta_data) $custom_meta = [ '_collection' => $item['collection'], '_tva' => $item['tax'], '_nombrepages' => $item['nbPages'], '_editor' => $item['editor'], '_date' => $item['publish_dateTxt'], '_author' => $item['autors'], '_productForm' => $item['ProductForm'], '_ProductAvailability' => $item['ProductAvailability'], ]; foreach ($custom_meta as $key => $value) { $product->update_meta_data($key, $value); } // 优化图片设置:跳过插件的复杂逻辑,直接写入元数据(导入后再批量处理缩略图) if (!empty($item['link_image'])) { $product->update_meta_data('_fifu_image', $item['link_image']); // 若插件需要其他操作,可在导入完成后批量触发,避免单条处理的耗时 } // 一次性保存产品(仅一次数据库写入操作) $product->save(); }
2. 禁用WordPress/WooCommerce的不必要功能
导入过程中,很多默认钩子和功能会消耗资源,临时禁用它们能大幅提升速度:
// 放在脚本最开头 define('WP_POST_REVISIONS', false); // 禁用文章修订版本 define('AUTOSAVE_INTERVAL', 86400); // 关闭自动保存 // 延迟术语、评论计数更新(导入完成后自动恢复) wp_defer_term_counting(true); wp_defer_comment_counting(true); // 禁用WooCommerce新产品通知、库存检查等非必需操作 remove_action('woocommerce_new_product', 'wc_send_new_product_notifications'); remove_action('woocommerce_process_product_meta', 'wc_process_product_meta_stock');
3. 批量处理数据,减少数据库交互
单条插入会产生大量数据库查询,积累一定数量的产品数据后批量写入,能将速度提升数倍:
批量插入示例(直接操作数据库,需谨慎)
global $wpdb; $batch_size = 100; // 每100条批量插入 $post_data = []; $meta_data = []; $term_rel_data = []; foreach ($xml_products as $index => $item) { // 组装post数据 $post = [ 'post_title' => $item['titre_produit'], 'post_content' => $item['resume'], 'post_status' => 'publish', 'post_type' => 'product', 'post_excerpt' => $item['resume'], ]; $post_data[] = $wpdb->prepare("(%s, %s, %s, %s, %s)", $post['post_title'], $post['post_content'], $post['post_status'], $post['post_type'], $post['post_excerpt'] ); // 组装自定义元数据(待post插入后获取ID再关联) $meta_data[] = [ 'sku' => $item['sku'], 'price' => $item['price'], 'custom_fields' => [ '_collection' => $item['collection'], '_tva' => $item['tax'], // ...其他自定义字段 ] ]; // 达到批量阈值时执行插入 if (($index + 1) % $batch_size === 0) { // 批量插入post表 $wpdb->query("INSERT INTO {$wpdb->posts} (post_title, post_content, post_status, post_type, post_excerpt) VALUES " . implode(', ', $post_data)); $last_post_id = $wpdb->insert_id; // 批量插入postmeta表 $meta_values = []; for ($i = 0; $i < $batch_size; $i++) { $current_post_id = $last_post_id - $batch_size + 1 + $i; // 添加WooCommerce核心元数据 $meta_values[] = $wpdb->prepare("(%d, %s, %s)", $current_post_id, '_sku', $meta_data[$i]['sku']); $meta_values[] = $wpdb->prepare("(%d, %s, %s)", $current_post_id, '_regular_price', $meta_data[$i]['price']); // 添加自定义字段 foreach ($meta_data[$i]['custom_fields'] as $key => $value) { $meta_values[] = $wpdb->prepare("(%d, %s, %s)", $current_post_id, $key, $value); } } $wpdb->query("INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) VALUES " . implode(', ', $meta_values)); // 批量关联分类 $term_rel_values = []; for ($i = 0; $i < $batch_size; $i++) { $current_post_id = $last_post_id - $batch_size + 1 + $i; $term_rel_values[] = $wpdb->prepare("(%d, %d, %d)", $current_post_id, $uncategorized_term_id, 0); } $wpdb->query("INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . implode(', ', $term_rel_values)); // 重置批量数组 $post_data = []; $meta_data = []; $term_rel_data = []; } } // 处理剩余的不足批量的数据(逻辑同上) // 导入完成后更新分类计数 wp_update_term_count_now([$uncategorized_term_id], 'product_cat');
注意:直接操作数据库需确保对WooCommerce表结构熟悉,避免破坏数据完整性。
4. 服务器与数据库优化
- MySQL配置优化:增大
innodb_buffer_pool_size(建议设置为服务器内存的50%-70%)、调整innodb_log_file_size、开启查询缓存(或使用Redis缓存替代)。 - 启用PHP OPcache:在php.ini中配置
opcache.enable=1、opcache.memory_consumption=128、opcache.max_accelerated_files=10000,避免重复编译PHP脚本。 - 控制并发数:不要盲目运行多个脚本实例,数据库连接竞争会导致速度下降,建议使用2-4个进程,或用队列系统(如Redis)异步处理。
5. 排查瓶颈点
- 开启MySQL慢查询日志,定位耗时最长的查询,针对性优化。
- 测试
fifu_dev_set_image函数的耗时,若该函数涉及远程图片下载、缩略图生成,可改为导入后批量处理,避免单条导入时阻塞流程。
内容的提问来源于stack exchange,提问作者Anatole
相关产品推荐
相关产品推荐

