【发布时间】:2023-04-10 23:04:01
【问题描述】:
我有三个表,wp_posts(60000 条记录)、wp_postmeta(130000 条记录)和 news_news_obj(70000 条记录)。 我想从 news_news_obj 表中查找表 wp_posts 中缺少的所有帖子。 与 news_news_obj.id 进行比较,每个帖子在 wp_postmeta 表 (oldpostid) 中都有一个自定义字段。
我首先尝试使用下面的 2 个查询,限制为 30,使用 NOT IN 的查询比使用 Joins 的查询更快。 问题是,当我删除 LIMIT 时,查询需要的时间太长了。我尝试将其放置几个小时,但没有返回任何结果。
对于这种问题,这么大的数据,我能做些什么?
任何帮助表示赞赏!
第一个带有连接的查询:
SELECT meta2.id, meta2.title, meta2.main_text
FROM wp_posts
INNER JOIN wp_postmeta meta1 ON meta1.post_id = wp_posts.ID
AND meta1.meta_key = 'oldpostid'
AND wp_posts.post_type = 'post'
RIGHT JOIN news_news_obj meta2 ON meta1.meta_value = meta2.id
WHERE meta1.meta_value IS NULL
我尝试使用 NOT IN 的第二个查询:
SELECT news_news_obj.id, news_news_obj.title, news_news_obj.main_text
FROM news_news_obj
WHERE news_news_obj.id NOT IN (
SELECT wp_postmeta.meta_value
FROM wp_posts, wp_postmeta
WHERE wp_posts.ID = wp_postmeta.post_id
AND wp_postmeta.meta_key = 'oldpostid'
AND wp_postmeta.meta_value = news_news_obj.id
AND wp_posts.post_status = 'publish'
AND wp_posts.post_type = 'post'
)
【问题讨论】:
-
是否有理由第二个查询关心“发布”而第一个不关心?另外,考虑到桌子的大小,我并不积极;但是从第二个版本的子查询中取出
AND wp_postmeta.meta_value = news_news_obj.id可能会有所帮助(因为它不再是相关的子查询,mysql 可以处理一次子查询,而不是为每个外行处理一次。) -
不,没有原因,我只是忘记将它添加到第一个查询中。目前,我主要关心的是在合理的时间限制内获得任一查询的结果。
-
因为这是我正在检查帖子是否存在于第二个表中的部分,你知道如果我删除这部分,如何以不同的方式完成吗?
-
请为
NOT IN和JOIN提供EXPLAIN SELECT ...-- 我想看看你为什么会有不同。另外,您使用的是哪个版本的 MySQL? -
您想要
FROM x INNER JOIN (y RIGHT JOIN z)还是FROM (x INNER JOIN y) RIGHT JOIN z)?请添加括号以澄清;然后检查您是否仍然得到“正确”的结果。
标签: mysql sql performance join large-data