web-dev-qa-db-ja.com

リソースの問題:外部データをカスタム投稿タイプにインポートし、レコードを最新の状態に保つ

毎晩外部データをインポートするカスタム投稿タイプがあります。インポートスクリプトが初めて実行されると、約4,000レコードがインポートされます(データは大きくなります)。各レコードは、役職、本文、および15の追加メタフィールドで構成されています。

インポートが少なくとも1回実行されると、それ以降のすべての夜に、各レコードから少なくとも1つのメタフィールドが更新され、レコードが外部データセットに存在し、最新であることが示されます。

外部データには、レコードがWordPressの外部で変更された時期を示す変更日フィールドが含まれています。インポートスクリプトがレコードの変更を検出すると、すべてのフィールドを更新します。

インポートの最後に、内部スクリプトがすべてのレコードを調べて、更新されなかったレコードを見つけます。レコードが更新されなかった場合は、削除フラグが設定され、公開状況が変更されます。そのレコードは最終的に削除されます。

最後に、各レコードはWordPressで上書きすることができます。これはインポート中にこの投稿が更新されるべきではないというフラグを設定します。これは、レコードがサイトに表示される前にデータコントロールを提供するため、カスタム投稿タイプに配置することを決定した理由の1つです。

レコードの挿入と更新にwp_insert_post、メタフィールドの挿入と更新にupdate_post_meta、現在のレコードと期限切れのレコードをすべて取得するWP_Queryを使用し、最終的に必要なレコードを削除します。 wp_delete_postdelete_post_metaで削除されます。

問題は、このスクリプトを実行するにはリソースが多すぎるため、WordPressがタイムアウトしてスクリプトが完了しないことです。

私は2つの選択肢があると思います。

  1. このスクリプトをいくつかのバッチに分けます。たとえば、一度に1,000レコードを処理して、2回目の繰り返し処理中にどこでピックアップするかがわかるようにインデックスを格納できます。
  2. 私は別の機能を試してみることができます。たとえば、最初のインポート中に、フィールドごとに1回update_post_metaを実行します(15x)。私はおそらくカスタムクエリを介してその1つのクエリを作成する方法を見つけることができました。

私の質問は、データを外部ソースと同期させるときに誰かがWordPressのリソースの問題に遭遇したことがあるかどうか、そしてそれらがどのようにしてそれらの問題を軽減したかです。それはオプション#1、#2、あるいはおそらくまったく異なる方法によるのでしょうか。

3
NightHawk

大量の投稿をインポート/更新することで見つけた大きな助けの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ステートメントを作成します。これは、トランザクションがあると大きな効果が得られるためです。

1
webaware