微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UNION ALL MYSQL 真的很慢

如何解决UNION ALL MYSQL 真的很慢

我在 MysqL 中有一个查询,有 2 个选择。当我单独运行这些查询时,它们会在 1 秒内快速运行。但是当我将它们与 union all 结合起来时,网站会冻结,并且在 union all 中执行相同的查询至少需要 20 秒。

知道为什么会这样吗?想不通。

查看下面的查询

SELECT p.user_id,p.description,p.post_id,p.created_at,ps.username AS size_name,ps.username AS user_name,ps.avatar AS avatar,pz.title AS title,pz.slug AS slug 
FROM comments p 
JOIN users ps ON ps.id = p.user_id 
JOIN posts pz ON pz.id = p.post_id 

UNION ALL

SELECT p2.user_id,p2.description,p2.post_id,p2.created_at,ps2.username AS size_name,ps2.username AS user_name,ps2.avatar AS avatar,pz2.title AS title,pz2.slug AS slug 
FROM reply p2 
JOIN users ps2 ON ps2.id = p2.user_id 
JOIN posts pz2 ON pz2.id = p2.post_id 

order by created_at DESC 
LIMIT 10

解决方法

在与UNION合并之前,减少每个子查询返回的表的大小。由于您只想要前 10 个,因此您只需要每个子查询的前 10 个。

SELECT *
FROM (
    (SELECT p.user_id,p.description,p.post_id,p.created_at,ps.username AS size_name,ps.username AS user_name,ps.avatar AS avatar,pz.title AS title,pz.slug AS slug 
    FROM comments p 
    JOIN users ps ON ps.id = p.user_id 
    JOIN posts pz ON pz.id = p.post_id 
    ORDER BY created_at DESC
    LIMIT 10) 
    
    UNION ALL
    
    (
    SELECT p2.user_id,p2.description,p2.post_id,p2.created_at,ps2.username AS size_name,ps2.username AS user_name,ps2.avatar AS avatar,pz2.title AS title,pz2.slug AS slug 
    FROM reply p2 
    JOIN users ps2 ON ps2.id = p2.user_id 
    JOIN posts pz2 ON pz2.id = p2.post_id 
    ORDER BY created_at DESC
    LIMIT 10)
) AS x
order by created_at DESC 
LIMIT 10
,

UNION 默认为 UNION DISTINCT。如果您想要 UNION ALL,请明确说明(并且您应该尽可能,因为 UNION DISTINCT 必须做很多工作才能使它们与众不同)。

另一件事是 order by 和 limit 适用于整个查询。您可能想让每个联合查询也包含它们。见https://dev.mysql.com/doc/refman/8.0/en/union.html

联合中的 ORDER BY 和 LIMIT

要将 ORDER BY 或 LIMIT 子句应用于单个 SELECT,请将 SELECT 括起来并将子句放在括号内:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

如果您的快速个人版本确实有这些,那应该会有所帮助。所以是这样的:

(SELECT p.user_id,pz.slug AS slug 
FROM comments p 
JOIN users ps ON ps.id = p.user_id 
JOIN posts pz ON pz.id = p.post_id 
order by created_at DESC 
LIMIT 10)

UNION ALL

(SELECT p2.user_id,pz2.slug AS slug 
FROM reply p2 
JOIN users ps2 ON ps2.id = p2.user_id 
JOIN posts pz2 ON pz2.id = p2.post_id 
order by created_at DESC 
LIMIT 10)

order by created_at DESC 
LIMIT 10

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。