两个建议:
1) 不要将旧的逗号连接语法与新的 JOIN 关键字语法混用
2) 在语句中创建表别名唯一(不要重复使用um 别名)
我认为我们不需要对 usermeta 表进行两次连接。我怀疑我们想要返回一个与此查询返回的结果集类似的结果集:
SELECT u.id AS name
, m.nickname AS nickname
, m.first_name AS first_name
FROM users u
LEFT
JOIN (SELECT um.umeta_id
, MAX(CASE WHEN um.meta_key='nickname' THEN um.meta_value END) AS nickname
, MAX(CASE WHEN um.meta_key='first_name' THEN um.meta_value END) AS first_name
FROM usermeta um
GROUP
BY um.umeta_id
) m
ON m.umeta_id = u.id
ORDER BY u.id
这只是一个猜测。如果没有规范、示例数据和预期结果,我们只是猜测。
跟进
作为连接的替代方法,我们可以在 SELECT 列表中使用相关子查询。例如:
SELECT u.id AS name
, ( SELECT umn.meta_value
FROM usermeta umn
WHERE umn.umeta_id = u.id
AND umn.meta_key='nickname'
ORDER BY umn.meta_value DESC
LIMIT 1
) AS nickname
, ( SELECT umn.meta_value
FROM usermeta umn
WHERE umn.umeta_id = u.id
AND umn.meta_key='first_name'
ORDER BY umn.meta_value DESC
LIMIT 1
) AS first_name
FROM users u
ORDER BY u.id
对于外部查询返回的合理数量的行,我们可以获得合理的性能,只要我们在usermeta表上定义了合适的索引,(umeta_id,meta_key)的前导列。理想情况下,覆盖索引还包括meta_value。
这些子查询将为外部查询返回的每一行和每一行执行,因此如果我们返回大量行,这些子查询真的会降低性能。