0

我正在查询 wordpress 帖子表中的一些帖子,并通过多次加入 postmeta 表来获取多个元值。对于帖子列和元值,我也有许多条件。查询似乎有效,但我很好奇我是否将条件放在正确的位置。比较以下查询,哪个最有效/最有效地让我获得帖子 ID 及其相关元?

这个:

SELECT a.ID as `post_id`, b.meta_value as `metaval1`, c.meta_value as `metaval2`, d.meta_value as `metaval3`
FROM posts AS a
JOIN postmeta AS b ON (b.post_id = a.ID AND b.meta_key = 'metakey1')
LEFT JOIN postmeta as c ON (c.post_id = a.ID AND c.meta_key = 'metakey2')
LEFT JOIN postmeta as d ON (d.post_id = a.ID AND d.meta_key = 'metakey3')
WHERE
    b.meta_value != 10
    AND a.post_status = 'pending'
    AND a.post_date < '2013-03-07 00:00:00'
    AND a.post_type = "post"
ORDER BY a.post_date DESC
LIMIT 100;

或者这个:

SELECT a.ID as `post_id`, b.meta_value as `metaval1`, c.meta_value as `metaval2`, d.meta_value as `metaval3`
FROM posts AS a
JOIN postmeta AS b ON (b.post_id = a.ID)
LEFT JOIN postmeta as c ON (c.post_id = a.ID)
LEFT JOIN postmeta as d ON (d.post_id = a.ID)
WHERE
    b.meta_key = 'metakey1'
    AND b.meta_value != 10
    AND c.meta_key = 'metakey2'
    AND d.meta_key = 'metakey3'
    AND a.post_status = 'pending'
    AND a.post_date < '2013-03-07 00:00:00'
    AND a.post_type = "post"
ORDER BY a.post_date DESC
LIMIT 100;

任何意见,将不胜感激 :)

4

1 回答 1

0

您的两个查询之间存在差异。

第一个查询将返回帖子的值,而不管匹配的元键值的数量(至少对于“b”值不是 10 的帖子)。您正在on子句中进行比较,因此left join处理结果。

第二个查询将仅在所有三个键都存在时返回值。比较在where子句中,所以由 生成的不匹配的行将left join被过滤掉。

您喜欢哪个取决于您想要的结果。两者都应该花费大约相同的计算量。

如果你想要效率,你还应该尝试:

SELECT p.id,
       max(case when pm.meta_key = 'metakey1' then pm.meta_value end) as metavalue1,
       max(case when pm.meta_key = 'metakey2' then pm.meta_value end) as metavalue2,
       max(case when pm.meta_key = 'metakey3' then pm.meta_value end) as metavalue3
FROM posts p join
     postmeta pm
     on pm.post_id = p.ID
WHERE pm.meta_key in ('metakey1', 'metakey2', 'metakey3') and
      (pm.meta_key <> 'metakey1' or pm.meta_value != 10) and
      p.post_status = 'pending' and
      p.post_date < '2013-03-07 00:00:00' and
      p.post_type = 'post'
group by p.post_date, p.id
ORDER BY p.post_date DESC
LIMIT 100;

这限制了连接的数量,使用聚合将结果放在一起。您的原始查询必须扫描结果以执行order by- 聚合应该是大约相同数量的工作,但连接更少。

于 2013-03-22T20:15:44.393 回答