毎晩外部データをインポートするカスタム投稿タイプがあります。インポートスクリプトが初めて実行されると、約4,000レコードがインポートされます(データは大きくなります)。各レコードは、役職、本文、および15の追加メタフィールドで構成されています。
インポートが少なくとも1回実行されると、それ以降のすべての夜に、各レコードから少なくとも1つのメタフィールドが更新され、レコードが外部データセットに存在し、最新であることが示されます。
外部データには、レコードがWordPressの外部で変更された時期を示す変更日フィールドが含まれています。インポートスクリプトがレコードの変更を検出すると、すべてのフィールドを更新します。
インポートの最後に、内部スクリプトがすべてのレコードを調べて、更新されなかったレコードを見つけます。レコードが更新されなかった場合は、削除フラグが設定され、公開状況が変更されます。そのレコードは最終的に削除されます。
最後に、各レコードはWordPressで上書きすることができます。これはインポート中にこの投稿が更新されるべきではないというフラグを設定します。これは、レコードがサイトに表示される前にデータコントロールを提供するため、カスタム投稿タイプに配置することを決定した理由の1つです。
レコードの挿入と更新にwp_insert_post
、メタフィールドの挿入と更新にupdate_post_meta
、現在のレコードと期限切れのレコードをすべて取得するWP_Query
を使用し、最終的に必要なレコードを削除します。 wp_delete_post
とdelete_post_meta
で削除されます。
問題は、このスクリプトを実行するにはリソースが多すぎるため、WordPressがタイムアウトしてスクリプトが完了しないことです。
私は2つの選択肢があると思います。
update_post_meta
を実行します(15x)。私はおそらくカスタムクエリを介してその1つのクエリを作成する方法を見つけることができました。私の質問は、データを外部ソースと同期させるときに誰かがWordPressのリソースの問題に遭遇したことがあるかどうか、そしてそれらがどのようにしてそれらの問題を軽減したかです。それはオプション#1、#2、あるいはおそらくまったく異なる方法によるのでしょうか。
大量の投稿をインポート/更新することで見つけた大きな助けの1つは、InnoDBのテーブルとトランザクションを200〜500投稿のバッチで使用することです(より多くのpostmetaを使用する場合は、より小さな投稿バッチを使用します)。その多くが個々のMySQLステートメントであり、それぞれがある時点でdbトランザクションログにヒットしなければならないことを考えると、パフォーマンスが大幅に向上します。そう:
$wpdb->query('start transaction');
を発行する$wpdb->query('commit');
ともう1つ$wpdb->query('start transaction');
を発行します。$wpdb->query('commit');
を発行します。$wpdb->query('rollback');
を発行それが終わったら、#2でpostmetaを調べ、postmetaを一度に挿入(または更新)するための単一のSQLステートメントを作成します。これは、トランザクションがあると大きな効果が得られるためです。