首页 > 解决方案 > 清理 WordPress wp_postmeta 表

问题描述

我正在查看我的 WordPress 数据库中的所有表,并注意到该wp_postmeta表有很多旧的和过时的信息。例如,它包含许多元键设置为_wp_attached_file,的条目_wp_attachment_metadata。这些_wp_attached_file值都是指向我的 WordPress 库中不再存在的旧文件的链接。

旧插件中还有一些其他条目似乎是多余的。

我想知道是否有办法清理表中的数据。经过一番研究,我找到了这篇文章。在我对表名进行适当更改后,页面上列出的 SQL 查询确实有效。

以下是原始查询:

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;

我没有在我的数据库上运行 DELETE 查询。但是,运行 SELECT 查询给了我以下结果。

在看到很多 NULL 值之后,我猜查询确实选择了冗余值。我现在应该运行 DELETE 查询吗?

另外,我只知道基本的 SQL,所以无法理解查询是如何工作的。谁能给我解释一下?

在此处输入图像描述

标签: phpmysqlwordpress

解决方案


是的,您可以运行DELETE. 就个人而言,我会创建一个将要删除的行的备份表,然后引用它。

SELECT uery 演示了反连接模式

 SELECT pm.* 
   FROM wp_postmeta pm 
     -- anti-join - only return rows from pm that do NOT have a matching row in wp
   LEFT
   JOIN wp_posts wp 
     ON wp.id = pm.post_id 
  WHERE wp.id IS NULL

LEFT JOIN外连接;这表示返回左侧表中的所有行(在本例中pm)以及右侧表中的匹配行(wp)。

考虑外连接作用的一种方法是,如果 中没有匹配的行wp,则继续创建一个包含所有 NULL 值的虚拟行,并返回该虚拟行。

这个查询的技巧是 WHERE 子句中的条件。wp保证匹配的任何行都具有非 NULL 值wp.id,因为只有非 NULL 值才能满足 ON 子句中的相等比较。任何 NULL 值都不会匹配。(此外,它很可能id是表中保证为非 NULL 的列。)

在连接操作之后,任何具有 NULL 值wp.id的结果行都是由外部连接生成的虚拟行的结果。所以我们知道在wp.

生成等效结果的另一种方法是使用NOT EXISTS (correlated subquery)谓词。

 SELECT pm.* 
   FROM wp_postmeta pm 
  WHERE NOT EXISTS 
        ( SELECT 1 
            FROM wp_posts wp 
           WHERE wp.id = pm.post_id
        )

我会创建要删除的行的备份:

 CREATE TABLE _backup_db_._backup_20190813_delete_from_pm_ 
 AS 
 SELECT pm.*
   FROM wp_postmeta pm 
     -- anti-join - only return rows from pm that do NOT have a matching row in wp
   LEFT
   JOIN wp_posts wp 
     ON wp.id = pm.post_id 
  WHERE wp.id IS NULL

然后我会在 中引用备份表DELETE,并使用引用目标表主键的连接。

假设这里id是表中的 PRIMARY KEY post_meta(我们需要检查,而不仅仅是猜测),我会先写为 SELECT:

 SELECT t.*
   FROM _backup_db_._backup_20190813_delete_from_pm   s
   JOIN post_meta t 
     ON t.id = s.id 

进行测试,然后通过将 SELECT 关键字替换为 DELETE 关键字来转换为删除语句

*请注意,使用表 alias 限定是非常重要的t.*


推荐阅读