WordPressのデータベースのゴミデータを削除する

私のサイトではフォーラムとして「BBPress」を使っているのだが、最近スパムの投稿が多くて、データベースのパフォーマンスがかなり落ちていた。定期的にスパムを削除していなかったこともあって、スパム認定されたデータがpostsテーブルに5万件以上、postmetaテーブルには34万件も溜まっていた…orz

これはイカン…と、管理画面からスパムをすべて削除を実行したところ、クエリが重すぎて500エラーになってしまった。

仕方ないので、コマンドラインからデータベースに直接ログインしてpostsテーブルのスパムは駆除した。だが、postmetaテーブルなどのリレーションテーブル系からのスパムデータ駆除が何気に面倒なことに気づいた。
先に親テーブル(postsテーブル)のスパム投稿を削除しているので、postmetaテーブルにおける駆除対象は親となる投稿IDが存在していないデータになる。通常のDELETE文の条件式で考えると、外部キーのpost_idからpostsテーブルに該当するプライマリキーがないことを確認して、なければ対象のmeta_idのデータを削除する…みたいなループ処理を作らないと…とか面倒なことを考えていたのだが、そういえばSQLにはNOT EXISTSサブクエリーという機能があったじゃないか!─とひらめいた。

ついでに今後のことも考えて、リレーションテーブル系の連結が外れているゴミデータを掃除するスクリプトを作ってみた次第。

このPHPスクリプトをWordPressのインストールディレクトリ直下にcleanup.phpとか名前をつけて置いて実行すると、各種リレーションテーブルにて親テーブルに連携元となるデータが存在しないデータのみをごっそり削除してくれる。

私も無事に35万件もあったpostmetaテーブルのクリーンアップができて、2700件にまで減りました(いやぁ、良かった良かった…)。

この機能、いつかCDBT V2に取り込んでおこう。

しっかし、BBPressのスパム量にはげんなりする…近く、フォーラムはWordPress.orgに集約してしまった方が無難かもしれない…。

Leave a Reply

Your email address will not be published.