[WordPress] 清除無關聯的孤兒資料與批次刪除使用者或內容的方法

本篇文章更新時間:2021/05/22
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


WordPress 外掛很多我知道,不過使用外掛來做本文操作對我來說有兩大隱憂。

  1. 外掛是在 WordPress 系統下執行。這句話也有兩個層面的意思:一是如果外掛執行操作時毀了 WordPress 執行的程序,WordPress 會壞掉,而外掛本身也會執行到一半壞掉,處理壞一半的東西更麻煩。二是效能上多執行一層 WordPress 系統,效率不高,速度反而慢。(所以用 WordPress 外掛來備份 WordPress 這件事我一直都不是很推薦,不過這討論下去就太進階了。)

  2. 你不確定外掛執行了哪些操作,結果真能如預期?看不懂程式的新手自然是假定外掛如預期執行,但也只能賭。碰到如前述的問題,可就頭痛了!所以如果自己知道怎處理方便,我會選擇自己先實作,而不是先找外掛。

對,沒錯!這開頭就是在說那些「WordPress 最佳化」相關關鍵字的外掛。

最佳化 WordPress 網站的方式很多,以下分享的操作都不適合看不懂的人。(意思是:請你真的知道自己在幹嘛才去操作!)

下方範例資料表請根據自己設定的前綴符號來使用

刪除 WooCommerce 訂單相關資料

DELETE FROM wp_woocommerce_order_itemmeta;
DELETE FROM wp_woocommerce_order_items;
DELETE FROM wp_comments WHERE comment_type = 'order_note';
DELETE FROM wp_postmeta WHERE post_id IN ( SELECT ID FROM wp_posts WHERE post_type = 'shop_order' );
DELETE FROM wp_posts WHERE post_type = 'shop_order';

操作完上述資料清理,也回到 wp_posts 裏確認還有沒有過去更新的遺毒。

SELECT post_type FROM wp_posts WHERE true GROUP BY post_type

通常確認一下還有沒有相關的內容類型被記錄著就差不多。

刪除 WooCommerce 商品相關資料

DELETE FROM wp_postmeta WHERE post_id IN ( SELECT ID FROM wp_posts WHERE post_type IN ( 'product', 'product_variation' );
DELETE FROM wp_posts WHERE post_type IN ( 'product', 'product_variation' );

刪除 WooCommerce 優惠券相關資料

DELETE FROM wp_postmeta WHERE post_id IN ( SELECT ID FROM wp_posts WHERE post_type = 'shop_coupon' );
DELETE FROM wp_posts WHERE post_type = 'shop_coupon';

刪除 WooCommerce 訂單備註相關資料

DELETE FROM wp_commentmeta WHERE comment_id IN ( SELECT ID FROM wp_comments WHERE comment_type = 'order_note' );
DELETE FROM wp_comments WHERE comment_type = 'order_note';

刪除 WordPress / WooCommerce 顧客使用者資料

wp user list --field=ID --role=customer | xargs wp user delete --yes

使用 WP CLI 指令於主機上操作。這邊指令操作會協助把使用者的中繼資料一併刪除。

刪除 WordPress 媒體庫等內容資料

wp post delete --force $(wp post list --post_type='attachment' --format=ids)

使用 WP CLI 指令快速刪除指定的內容類型(媒體附件)

如果使用 $wpdb 方式可以參考這 Gist 做法:

function delete_custom_posts($post_type = 'post'){
    global $wpdb;
    $result = $wpdb->query( 
        $wpdb->prepare("
            DELETE posts,pt,pm
            FROM wp_posts posts
            LEFT JOIN wp_term_relationships pt ON pt.object_id = posts.ID
            LEFT JOIN wp_postmeta pm ON pm.post_id = posts.ID
            WHERE posts.post_type = %s
            ", 
            $post_type
        ) 
    );
    return $result!==false;
}

也能把非內建內容類型(Post Type)指定刪除其文章、中繼資料與分類資料。

移除沒關聯到的中繼資料

最後最後,如果曾經單純刪除過內容 posts,但沒處理到 postmeta 的話,可以使用下面方法找到這些孤兒資料並刪除。

確認有哪些資料:

SELECT * FROM wp_postmeta pm LEFT JOIN wp_posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;

刪除那些資料:

DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;

參考

  1. WooCommerce: Bulk Delete Orders / Products Super Fast
  2. How to Bulk Delete all WooCommerce Customer Accounts

後記

其實如果資料才幾百筆的話,內建的刪除功能自己點一點就搞定。會有這樣比較「技術」的做法就是那種好幾萬筆等級,又或是網站本身與主機的配置考量(網站跑起來太慢,剛好主機有提供進階操作的方法?)

如果市面上有這些整理與最佳化的外掛,他也是會用差不多的方法來處理網站,如同開頭所說,你不確定外掛的實作方式適不適合那就是賭。把源頭設計的用意讀懂來,也是學習一個框架的方式囉~


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon