从表格中我试图获得
a)满足某些条件的用户,这些条件以表格中的键/值组合保存
OR
b)根本没有该键/值组合的用户
因此,例如,要尝试查找居住在法国或尚未添加其位置的用户,请使用此(简化)查询:
SELECT *
FROM
current_users
JOIN current_users um_location ON current_users.id = um_location.id
WHERE
(
( um_location.meta_key = 'location' AND um_location.meta_value = 'France' )
OR
( current_users.id NOT IN
(SELECT current_users.id FROM current_users WHERE current_users.meta_key = 'location' )
)
)
问题是,当然,运行OR子选择查询(如果它被调用的话)会大大减慢查询速度。而且由于完整查询中有大约5个或6个这样的子选择,因此它的速度太慢了。
还有另一种方法吗?更快的方式?
答案 0 :(得分:0)
将OR条件更改为UNION查询而不是OR
SELECT * FROM
current_users
JOIN current_users um_location ON current_users.id = um_location.id
WHERE
um_location.meta_key = 'location' AND um_location.meta_value = 'France'
UNION
SELECT * FROM
current_users
JOIN current_users um_location ON current_users.id = um_location.id
WHERE
current_users.id NOT IN
(SELECT current_users.id FROM current_users WHERE
current_users.meta_key='location' )
答案 1 :(得分:0)
这应该是最简洁的:
SELECT *
FROM current_users
LEFT JOIN current_users AS um_location
ON current_users.id = um_location.id
AND um_location.meta_key = 'location'
WHERE um_location.meta_value = 'France'
OR um_location.meta_value IS NULL
;
...但是作为isaace的回答提示,MySQL并不理想地处理OR条件。 所以,这可能会表现得更好。
SELECT *
FROM current_users
LEFT JOIN current_users AS um_location
ON current_users.id = um_location.id
AND um_location.meta_key = 'location'
WHERE um_location.meta_value = 'France'
UNION
SELECT *
FROM current_users
LEFT JOIN current_users AS um_location
ON current_users.id = um_location.id
AND um_location.meta_key = 'location'
WHERE um_location.meta_value IS NULL
;
..如果你有meta_value索引,它可能只会有所作为;因为问题是MySQL在呈现OR时会倾向于忽略索引。
编辑:由于开始使用架构设计的类型,这些查询可能会出现一些奇怪的问题,使用“位置”条目作为连接左侧的行;试试这个。
SELECT *
FROM current_users AS non_location
LEFT JOIN current_users AS um_location
ON current_users.id = um_location.id
AND um_location.meta_key = 'location'
WHERE non_location.meta_key != 'location'
AND (um_location.meta_value = 'France'
OR um_location.meta_value IS NULL
)
;
答案 2 :(得分:0)
首先,谢谢你们的建议。不幸的是,我无法让它们作为连接工作
LEFT JOIN current_users AS um_location
ON current_users.id = um_location.id
AND um_location.meta_key = 'location'
没有返回那些尚未进入其位置的用户的记录。
但是,经过大量的工作,我设法解决了这个问题。它不优雅,但有效:
然后最终查询包括:
um_location.meta_value = 'France'
or
um_location.meta_value = 'dummyinfo'
它的速度并不快,但由于这是一个仅为管理员用户服务的过程,因此他们可以等待......;)
再次感谢您的帮助!