在mysql中合并简单选择(join或union?)

时间:2019-07-18 01:43:38

标签: mysql

我有两个查询都很快(20毫秒)-当我将它们与联接结合在一起时,我得到了30秒的查询,并且数据有误...什么地方出了错?

SELECT
    count(profile.id),
    date(profile.createdAt)
FROM profile
GROUP BY date(profile.createdAt)
ORDER BY date(profile.createdAt) DESC;

SELECT
    count(product.id),
    date(product.createdAt)
FROM product
GROUP BY date(product.createdAt)
ORDER BY date(product.createdAt) desc;

加入它们后,我得到一个非常慢的查询:

SELECT
    count(profile._id),
    date(profile.createdAt),
    count(product._id),
    date(product.createdAt)
FROM profile
    INNER JOIN product
    ON date(product.createdAt) = date(profile.createdAt)
GROUP BY 
    date(product.createdAt), 
    date(profile.createdAt)
ORDER BY date(product.createdAt) desc;

2 个答案:

答案 0 :(得分:2)

当前方法的逻辑错误是由于连接而重复计算了一个或两个计数。您可以尝试在单独的子查询中进行聚合,然后加入这些子查询:

SELECT
    t1.createdAt,
    COALESCE(t1.profile_cnt, 0) AS profile_cnt,
    COALESCE(t2.product_cnt, 0) AS product_cnt
FROM
(
    SELECT DATE(createdAt) AS createdAt, COUNT(id) AS profile_cnt
    FROM profile
    GROUP BY DATE(createdAt)
) t1
INNER JOIN
(
    SELECT DATE(createdAt) AS createdAt, COUNT(id) AS product_cnt
    FROM product
    GROUP BY DATE(createdAt)
) t2
    ON t1.createdAt = t2.createdAt;

如果两个表都不包含相同的日期,则上述查询可能会删除某些日期。为避免这种情况,我们可以加入一个日历表,其中包含了我们希望出现在输出中的所有日期。

关于性能,您正在执行两个聚合查询的联接,因此预期不会有这种性能。另外,调用DATEcreatedAt强制转换为纯日期是昂贵的,并且可以通过维护专用日期列来避免。

答案 1 :(得分:0)

我认为问题在于您正在加入date函数的结果,这很可能在后台进行了很多工作。该功能必须对每个表中的每个记录执行。

如果可以,请与表的主键/外键结合使用索引。