来自两个连接表的求和的最佳性能查询

时间:2015-08-10 14:06:17

标签: mysql sql join subquery left-join

我有3张桌子:

客户

id
name

service_type1

id 
customer_id 
price (one to many relation to the customer)

service_type2

id
customer_id 
price (one to many relation to the customer)

我想列出这些值:nameservice_type1 – sum priceservice_type2 – sum price

我创建了两个执行我想要的查询:

A:

SELECT
    name,
    SUM(price) AS sum_price,
    (SELECT SUM(price)
        FROM service_type2
        WHERE customer_id = u.id
    ) AS sum_price2 
FROM customer u
LEFT JOIN service_type1 a ON a.customer_id = u.id
GROUP BY u.id
ORDER BY u.id

B:

SELECT
    name,
    SUM(price) AS sum_price,
    p.sum_price AS sum_price2
FROM customer u
LEFT JOIN service_type1 a ON a.customer_id = u.id
LEFT JOIN
(
    SELECT SUM(price) AS sum_price, customer_id
    FROM service_type2
    GROUP BY customer_id
) p ON p.customer_id = u.id
GROUP BY u.id
ORDER BY u.id

我对他们进行了基准测试,他们的执行时间是相同的*。是否可以编写更多以性能为导向的查询?

*这不是真的。每个表中有30k +记录,“A”快得多。

3 个答案:

答案 0 :(得分:1)

我可能认为使用适当的索引可以更好地使用此版本:

SELECT u.name,
       (SELECT SUM(st.price)
        FROM service_type1 st
        WHERE st.customer_id = u.id
       ) as sum_service_type1,
       (SELECT SUM(price)
        FROM service_type2 st
        WHERE st.customer_id = u.id
       ) as sum_price  
FROM customer u
ORDER BY u.id;

最佳索引是customer(id, name)service_type1(customer_id, price)service_type2(customer_id, price)

答案 1 :(得分:0)

如果我理解正确,请尝试:

SELECT id,sum_service_type1 INTO #T1 FROM service_type1 GROUP BY customer_id

SELECT id,sum_service_type2 INTO #T2 FROM service_type2 GROUP BY customer_id

SELECT name, sum_service_type1, sum_service_type2, FROM customer u LEFT JOIN #T1 a ON a.id = u.id LEFT JOIN #T2 b ON b.id = u.id

改进你可以创建一个聚集索引

答案 2 :(得分:0)

如何运行这两个查询,并在客户端使用合并排序将两个结果集合并为一个。 (它们已按u.id排序,因此我们可以轻松合并它。)

SELECT
    name,
    SUM(price) AS sum_service_type1,
FROM customer u
    LEFT JOIN service_type1 a ON a.customer_id = u.id
GROUP BY u.id
ORDER BY u.id;

SELECT
    name,
    SUM(price) AS sum_service_type2,
FROM customer u
    LEFT JOIN service_type2 a ON a.customer_id = u.id
GROUP BY u.id
ORDER BY u.id;

我认为如果2个查询的执行时间总和小于你的查询,那么在客户端实现它是可以负担得起的。