问题描述
我有一个我要插入的 csv 文件,包含〜 1,500 行和 97 列。做完全进口需要 2-3 个小时,如果有办法,我想改进一下。目前,对于每一行,我正在做一个 $ post_id = wp_insert_post,然后为每一行的 97 个关联列创建一个 add_post_meta 。这是非常低效的…
有没有更好的方式来解决这个问题,可以得到一个 post_id 保持帖子和它的 post_meta 值之间的关系?
现在我正在我的本地机器上尝试这个,但是会在 VPS 上运行
最佳解决方案
之前我有类似的问题,使用自定义 CSV 导入,但我最终使用一些自定义 SQL 进行批量插入。但是我当时没有看到这个答案:
Optimize post insert and delete for bulk operations?
使用 wp_defer_term_counting()
启用或禁用术语计数。
此外,如果您查看了 WordPress 导入器插件的 source,您将在批量导入之前看到这些功能:
wp_defer_term_counting( true );
wp_defer_comment_counting( true );
然后批量插入:
wp_defer_term_counting( false );
wp_defer_comment_counting( false );
所以这可能是要尝试的东西;-)
这是 @otto 的好提示:
批量插入之前,请明确禁用 autocommit
模式:
$wpdb->query( 'SET autocommit = 0;' );
批量插入后,运行:
$wpdb->query( 'COMMIT;' );
我也认为做一些家务的好主意像:
$wpdb->query( 'SET autocommit = 1;' );
我没有在 MyISAM 上测试这个,但这应该在 InnoDB 上工作。
次佳解决方案
您将需要插入帖子以获取您的 ID,但 $wpdb->postmeta
表的结构非常简单。您可能会使用直接的 INSERT INTO
语句,就像 MySQL 文档一样:INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
在你的情况下
$ID = 1; // from your wp_insert_post
$values = '($ID,2,3),($ID,5,6),($ID,8,9)'; // build from your 97 columns; I'd use a loop of some kind
$wpdb->query("INSERT INTO {$wpdb->postmeta} (post_id,meta_key,meta_value) VALUES {$values}");
这不会处理任何编码,序列化,转义,错误检查,重复或其他任何事情,但我希望它更快 (虽然我还没有尝试) 。
我不会在没有彻底测试的情况下在生产现场做到这一点,如果我只需要做一到两次,我会使用核心功能,并在进口时吃午饭。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。