电力公司开票系统多时间序列表查询性能优化请求
嘿,兄弟!第一次建数据库就能搞出电力开票系统,这已经很厉害了👍 咱们一步步来解决查询慢的问题,让你的系统能轻松扛住后面更复杂的计算。
先搞懂当前慢的原因
从你给的EXPLAIN结果能看出来:apxprice和powerload这两张表都在全表扫描(key列是null),只有imbalanceprice用到了索引。全表扫描几十万条数据再关联,速度肯定快不起来,而且越复杂的查询会越卡。
第一步:给另外两张表补全「精准的联合索引」
索引不是随便建的,要贴合你的查询逻辑来:
- 对
apxprice:你的查询需要用DATE关联,还要用PERIOD_FROM、PERIOD_UNTIL做范围判断,最后还要取PRICE计算。所以建一个包含这些字段的联合索引:
✅ 把CREATE INDEX idx_apx_date_period ON apxprice (DATE, PERIOD_FROM, PERIOD_UNTIL, PRICE);PRICE加进索引是为了「覆盖查询」——数据库直接从索引里拿数据,不用再去查整张表,速度会快很多。 - 对
powerload:查询用DATE和PERIOD_FROM关联,还要取POWERLOAD,所以建:CREATE INDEX idx_powerload_date_period ON powerload (DATE, PERIOD_FROM, POWERLOAD);
第二步:优化查询语句的写法
你用的是老式的逗号连接表,换成显式JOIN语法不仅更清晰,还能让数据库优化器更好地干活。另外还有个隐藏坑:你之前只按i.DATE分组,但SELECT里有PERIOD_FROM等非聚合字段,这在严格SQL模式下会报错,结果也不准确,必须把所有非聚合字段都加到GROUP BY里:
SELECT i.DATE, i.PERIOD_FROM, i.TAKE_FROM_SYSTEM, i.FEED_INTO_SYSTEM, a.PRICE, p.POWERLOAD, SUM(a.PRICE * p.POWERLOAD) AS total_amount FROM imbalanceprice i JOIN apxprice a ON i.DATE = a.DATE AND i.PERIOD_FROM >= a.PERIOD_FROM AND i.PERIOD_FROM < a.PERIOD_UNTIL JOIN powerload p ON i.DATE = p.DATE AND i.PERIOD_FROM = p.PERIOD_FROM WHERE i.DATE BETWEEN '2018-01-01' AND '2018-01-31' GROUP BY i.DATE, i.PERIOD_FROM, i.TAKE_FROM_SYSTEM, i.FEED_INTO_SYSTEM, a.PRICE, p.POWERLOAD;
第三步:把MyISAM换成InnoDB(可选但推荐)
MyISAM是老掉牙的引擎了,不支持事务,在关联查询多的场景下性能远不如InnoDB。InnoDB有聚簇索引、行级锁,缓存机制也更高效,迁移起来超简单:
ALTER TABLE apxprice ENGINE=InnoDB; ALTER TABLE imbalanceprice ENGINE=InnoDB; ALTER TABLE powerload ENGINE=InnoDB;
迁移后主键会自动变成聚簇索引,对查询速度又是一波提升。
第四步:应对更复杂的查询(比如按月份分组全年数据)
如果要查全年数据并按月份分组,用DATE_FORMAT就能轻松实现,而且之前建的索引依然能发挥作用:
SELECT DATE_FORMAT(i.DATE, '%Y-%m') AS month, SUM(a.PRICE * p.POWERLOAD) AS monthly_total FROM imbalanceprice i JOIN apxprice a ON i.DATE = a.DATE AND i.PERIOD_FROM >= a.PERIOD_FROM AND i.PERIOD_FROM < a.PERIOD_UNTIL JOIN powerload p ON i.DATE = p.DATE AND i.PERIOD_FROM = p.PERIOD_FROM WHERE i.DATE BETWEEN '2018-01-01' AND '2018-12-31' GROUP BY month;
最后别忘了验证效果
每次改完索引或语句,都跑一遍EXPLAIN看看:
apxprice和powerload的key列是不是显示了你新建的索引rows列的数字是不是变小了(扫描行数越少越快)extra列里的using temporary、filesort有没有减少
这样折腾完,你的查询速度肯定会有质的飞跃,后续加第三张电价表也能轻松hold住!
内容的提问来源于stack exchange,提问作者Introduction to programming
相关产品推荐
相关产品推荐

