我正在查询wordpress帖子表中的一些帖子,并通过多次加入postmeta表来获取多个元值。对于post列和meta值,我也有很多条件。查询似乎有效但我很好奇,如果我把条件放在正确的位置。比较以下查询,这将最有效/最有效地获得post 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;
任何建议都将受到赞赏:)
答案 0 :(得分:0)
两个问题之间存在差异。
第一个查询将返回帖子的值,无论匹配的metakey值的数量是多少(至少对于&#34; b&#34;值不是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
- 聚合应该与工作量相同,但连接次数较少。