【发布时间】:2017-10-06 19:22:45
【问题描述】:
我有以下 2 个 SQL 查询,95% 相同,但性能明显不同。
SQL 查询 1 (
SELECT CONCAT(a.`report_year`, '-', a. `report_month`) as `yearmonth`,
AVG(a.cost_leasing/b.rate*IF(`report_year`=2016,0.73235,
IF(`report_year`=2017,0.83430,1))) as average,
'current' as `type`
FROM `vehicles` as a, `exchange_rates` as b
WHERE cid='3' AND
STR_TO_DATE(CONCAT(`report_year`, '-', `report_month`, '-01'),
'%Y-%m-%d') >= '2016-01-01' AND
LAST_DAY(STR_TO_DATE(CONCAT(`report_year`, '-', `report_month`,
'-01'), '%Y-%m-%d')) <= '2017-06-30' AND
`country` IN ('XX','UK') AND
a.currency = b.currency AND
b.`year` = `report_year` AND
fxid=2
GROUP BY `yearmonth`
ORDER BY `yearmonth`;
解释查询 1:
1 SIMPLE a ref new_selectors,... new_cost_leasing 4 const 10812 Using where; Using index; Using temporary; Using f...
1 SIMPLE b ref PRIMARY,date,fxid fxid 19 const,c1682fleet.a.report_year,c1682fleet.a.curren... 196 Using where; Using index
SQL查询2(>3s):
SELECT CONCAT(c.`report_year`, '-', c.`report_month`) as `yearmonth`,
AVG(c.cost_leasing/d.rate*IF(`report_year`=2016,0.73235,
IF(`report_year`=2017,0.83430,1))),
'baseline'
FROM `kpis` as c, `exchange_rates` as d
WHERE cid='3' AND
STR_TO_DATE(CONCAT(`report_year`, '-', `report_month`, '-01'),
'%Y-%m-%d') >= '2016-01-01' AND
LAST_DAY(STR_TO_DATE(CONCAT(`report_year`, '-', `report_month`,
'-01'), '%Y-%m-%d')) <= '2017-06-30' AND
`country` IN ('XX','UK') AND
c.kid=1 AND
c.currency = d.currency AND
d.`year` = `report_year` AND
fxid=2
GROUP BY `yearmonth`
ORDER BY `yearmonth`;
解释查询 2:
1 SIMPLE c ref oem_group,... cost_leasing 8 const,const 30038 Using where; Using index; Using temporary; Using f...
1 SIMPLE d ref PRIMARY,date,fxid fxid 19 const,c1682fleet.c.report_year,c1682fleet.c.curren... 196 Using where; Using index
显示车辆索引:
vehicles 0 PRIMARY 1 vid A 146068 BTREE
vehicles 1 new_cost_leasing 1 cid A 12 BTREE
vehicles 1 new_cost_leasing 2 cost_leasing A 4564 BTREE
vehicles 1 new_cost_leasing 3 currency A 5216 BTREE
vehicles 1 new_cost_leasing 4 report_month A 24344 BTREE
vehicles 1 new_cost_leasing 5 report_year A 29213 BTREE
vehicles 1 new_cost_leasing 6 country A 36517 BTREE
vehicles 1 new_cost_leasing 7 supplier A 29213 BTREE
vehicles 1 new_cost_leasing 8 jato_segment A 24344 BTREE
vehicles 1 new_cost_leasing 9 business_unit A 36517 BTREE
vehicles 1 new_cost_leasing 10 entity A 73034 BTREE
从 exchange_rates 显示索引:
exchange_rates 0 PRIMARY 1 fxid A 2 BTREE
exchange_rates 0 PRIMARY 2 currency A 160 BTREE
exchange_rates 0 PRIMARY 3 date A 569250 BTREE
exchange_rates 1 date 1 fxid A 2 BTREE
exchange_rates 1 date 2 date A 28462 BTREE
exchange_rates 1 date 3 currency A 569250 BTREE
exchange_rates 1 date 4 rate A 569250 BTREE
exchange_rates 1 fxid 1 fxid A 2 BTREE
exchange_rates 1 fxid 2 year A 114 BTREE
exchange_rates 1 fxid 3 currency A 2904 BTREE
exchange_rates 1 fxid 4 rate A 569250 BTREE
显示来自 kpis 的索引:
kpis 0 PRIMARY 1 vid A 60308 BTREE
kpis 1 cost_leasing 1 cid A 2 BTREE
kpis 1 cost_leasing 2 kid A 2 BTREE
kpis 1 cost_leasing 3 cost_leasing A 78 BTREE
kpis 1 cost_leasing 4 currency A 78 BTREE
kpis 1 cost_leasing 5 report_month A 1096 BTREE
kpis 1 cost_leasing 6 report_year A 3350 BTREE
kpis 1 cost_leasing 7 country A 1884 BTREE
kpis 1 cost_leasing 8 supplier A 4020 BTREE
kpis 1 cost_leasing 9 jato_segment A 3015 BTREE
kpis 1 cost_leasing 10 business_unit A 4307 BTREE
kpis 1 cost_leasing 11 entity A 6030 BTREE
kpis 1 avg_cost 1 cid A 2 BTREE
kpis 1 avg_cost 2 kid A 2 BTREE
kpis 1 avg_cost 3 country A 48 BTREE
kpis 1 avg_cost 4 report_year A 96 BTREE
kpis 1 avg_cost 5 currency A 96 BTREE
kpis 1 avg_cost 6 cost_leasing A 172 BTREE
问题: 我的问题是,为什么即使查询 2 (kid) 中只有一个附加条件(甚至是索引的一部分),性能差异也会如此显着(因子 30)。
任何人知道如何优化查询 2?
【问题讨论】:
-
如果他们使用完全不同的表,我不会说他们 95% 相同。具有可能不同的结构、索引、记录数......需要更多信息。
-
表是相同的,除了 kpis 还包含字段
kid。索引相同,除了 kpi 索引还包含kid作为列之外,它们是相同的。您可以在解释答案中看到受影响的行。 -
你能发布你的索引定义吗?
-
请阅读此内容,并特别注意查询性能部分。 meta.stackoverflow.com/a/271056 请edit 您的问题提供更多信息。您的一个索引可能缺少一列,但我们不知道是哪一个。
-
我添加了相关的KPI指标。
标签: mysql sql select indexing query-performance