[英]Performance issue with my MYSQL query with subqueries
我的以下查询存在巨大的性能问题,我认为泄漏是什么,但不知道如何解决。
问题是内部选择遍历表中的所有记录,例如 200K,然后尝试选择并将过滤器应用于它,以便在第一轮中选择整个数据。
SELECT *
FROM (
SELECT
( SELECT GROUP_CONCAT(tp.login) login
FROM tp
WHERE tp.user_id = ue.user_id ) login,
u.email as email,
ue.fname as name
FROM user_extra ue
LEFT JOIN users u ON u.id = ue.user_id
) t
WHERE
email like '%sradesign.net@gmail.com%'
OR fname like '%test%'
OR login like '%461988%
测试我有没有搞错:
SELECT GROUP_CONCAT(tp.login) login,
u.email as email,
ue.fname as name
FROM user_extra ue
JOIN users u ON u.id = ue.user_id -- I doubt in LEFT
JOIN tp ON tp.user_id = ue.user_id
GROUP BY ue.fname,
u.email
-- , ue.user_id -- maybe needed, but I doubt
HAVING email like '%sradesign.net@gmail.com%'
OR fname like '%test%'
OR login like '%461988%
这是中间变体 - 它必须分为两个(或三个 - 取决于您的数据)单独的查询,稍后与 UNION 结合。
有时会发生一个用户没有任何登录名(tp 表中没有他的记录),但我想告诉他如果客户搜索词在 fname 的电子邮件中匹配,该怎么做? — 阿里·马哈茂迪
在这种情况下,必须使用外部连接 (LEFT JOIN) 连接此表。 – 秋菜
使用 left join 再次变得像之前的性能问题查询运行了 200 秒 – Ali Mahmoudi
正如我上面所说 - 这是中间变体。 如果它是正确的,那么让我们考虑到tp
可能不存在的情况进行划分:
SELECT GROUP_CONCAT(tp.login) login,
u.email as email,
ue.fname as name
FROM user_extra ue
JOIN users u ON u.id = ue.user_id -- I doubt in LEFT
LEFT JOIN tp ON tp.user_id = ue.user_id
WHERE u.email like '%sradesign.net@gmail.com%'
GROUP BY ue.fname,
u.email
UNION ALL
SELECT GROUP_CONCAT(tp.login) login,
u.email as email,
ue.fname as name
FROM user_extra ue
JOIN users u ON u.id = ue.user_id -- I doubt in LEFT
LEFT JOIN tp ON tp.user_id = ue.user_id
WHERE ue.fname like '%test%'
GROUP BY ue.fname,
u.email
UNION ALL
SELECT GROUP_CONCAT(tp.login) login,
u.email as email,
ue.fname as name
FROM user_extra ue
JOIN users u ON u.id = ue.user_id -- I doubt in LEFT
JOIN tp ON tp.user_id = ue.user_id
GROUP BY ue.fname,
u.email
HAVING login like '%461988%
测试其输出的正确性。
如果它将产生重复项,则将 UNION ALL 替换为 UNION DISTINCT。
SELECTs
。 这会导致包含大量数据的额外临时表。LEFT
会增加混乱并可能阻止某些优化。OR
很难优化。 但... 优化OR
常见技巧:
( SELECT ... WHERE email like '%sradesign.net@gmail.com%' )
UNION DISTINCT
( SELECT ... WHERE fname like '%test%' )
UNION DISTINCT
( SELECT ... WHERE login like '%461988% )
但是,由于JOINs
, UNION
可能不实用。
考虑使用FULLTEXT
而不是LIKE
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.