我有一个带有以下列的表的mysql数据库..
id
dealerId
month_year
total_price
total_count
vin_prefix
和表有2000万条记录,我希望获得ID为#02的经销商销售的所有汽车的总和(total_price)(这很简单)
但是,我希望得到所有其他经销商的总和,这些经销商与经销商#02
一样销售与vin_prefix相同的汽车所以我写了这个查询...
SELECT d.dealerId
FROM `dealer_monthly_report` d
where d.dealerId <> 2
and d.vin_prefix in (select distinct(d2.vin_prefix)
from `dealer_monthly_report` d2
where d2.dealerId = 2)
group by d.dealerId
但是我们可以以任何方式优化此查询吗? 索引已分别用于dealerId,vin_prefix和month_year。
谢谢!
答案 0 :(得分:1)
刚尝试了1.000.000记录的查询和Gordon的查询。通过添加索引dealer_monthly_report(vin_prefix, dealerId)
,您建议的查询似乎比Gordon的查询快一点(我的记录大约1-2秒)。
编辑:更正了临时表的代码
我建议将Gordon的第一个解决方案扩展如下:
CREATE TEMPORARY TABLE vin_prefixes_dealerID_2
SELECT distinct(d.vin_prefix) as vin_prefix
FROM `dealer_monthly_report` d
WHERE d.dealerID = 2
;
SELECT d.dealerId, sum(total_price)
FROM `dealer_monthly_report` d
WHERE d.dealerId <> 2 AND
EXISTS (
SELECT 1
FROM `vin_prefixes_dealerID_2` d2
where d.vin_prefix = d2.vin_prefix
)
GROUP BY d.dealerId;
这将查询时间从最初的18-20秒减少到大约6-7秒(对于1.000.000条记录)
修改:更正了替代方法
替代方法可能是:
CREATE TEMPORARY TABLE vin_prefixes_dealerID_2
SELECT distinct(d.vin_prefix) as vin_prefix
FROM `dealer_monthly_report` d
WHERE d.dealerID = 2
;
SELECT d.dealerId, sum(d.total_price)
FROM `dealer_monthly_report` d
JOIN `vin_prefixes_dealerID_2` d2
ON d.vin_prefix = d2.vin_prefix
WHERE d.dealerID <> 2
GROUP BY d.dealerId;
这将处理时间缩短到大约0.91(!!!)秒
答案 1 :(得分:0)
是的,它可能是。这是您的查询:
SELECT d.dealerId
FROM `dealer_monthly_report` d
WHERE d.dealerId <> 2 AND
d.vin_prefix in (select distinct d2.vin_prefix
from `dealer_monthly_report` d2
where d2.dealerId = 2
)
GROUP BY d.dealerId;
我会使用exists
重新编写查询:
SELECT d.dealerId
FROM `dealer_monthly_report` d
WHERE d.dealerId <> 2 AND
EXISTS (select 1
from `dealer_monthly_report` d2
where d2.dealerId = 2 and d.vin_prefix = d2.vin_prefix
)
GROUP BY d.dealerId;
然后,dealer_monthly_report(dealerId)
和dealer_monthly_report(vin_prefix, dealerId)
上的索引最适合提高效果。
如果您有vin_prefix
的经销商表,那么最佳方法根本没有group by
:
select dealerId d
from dealers d
where dealerid <> 2 and
exists (select d2.vin_prefix
from `dealer_monthly_report` dmr
where d2.dealerId = 2 and dmr.vin_prefix = d.vin_prefix
);
这将使用dealer_monthly_report(vin_prefix, dealerId)
和dealers(dealerid, vin_prefix)
上的索引。