提高这个慢查询的性能
Posted
技术标签:
【中文标题】提高这个慢查询的性能【英文标题】:improve the performance of this slow query 【发布时间】:2015-07-23 09:34:27 【问题描述】:我想调整这个查询以获得更好的性能。
查询:
SELECT `DeviceRawUsage`.`duration`, `DeviceRawUsage`.`current`
FROM `epowerg`.`device_raw_usages` AS `DeviceRawUsage`
WHERE `DeviceRawUsage`.`device_id` = 1 AND
`DeviceRawUsage`.`outlet_id` = 1 AND
`DeviceRawUsage`.`duration` >= '2015-06-01 00:00:00' AND
`DeviceRawUsage`.`duration` <= '2015-06-30 23:59:59';
【问题讨论】:
可能值得将LIMIT
添加到您想要返回的结果数量中 - 如果适用于这种情况。 IE。如果您想要 10 个结果:在查询末尾添加 LIMIT 10
。
@user3065931 我无法限制它。我希望尽可能多地调整查询。还有其他方法可以使这个查询高效吗?
您是否为您的列 device_id
、outlet_id
等定义了索引?
请告诉我们SHOW CREATE TABLE device_raw_usages
的输出
提供表定义、mysql 设置和最重要的EXPLAIN
的输出。 @user3065931 - LIMIT 在这里没有影响,它永远不会使选择更快 - 请阅读 LIMIT 如何在内部工作(MySQL 收集所有记录,然后丢弃从 OFFSET 开始的所有记录以获取 LIMIT 行数)。
【参考方案1】:
CREATE TABLE `device_raw_usages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`device_id` int(11) DEFAULT NULL,
`outlet_id` int(11) NOT NULL,
`duration` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`current` float(11,4) DEFAULT NULL,
`voltage` float(11,4) NOT NULL,
`kw_used` float NOT NULL,
`outlet_total_kwh` float(11,4) DEFAULT NULL,
`outlet_kwh_demand_15` float(11,4) DEFAULT NULL,
`outlet_kw_demand_peak` float(11,4) DEFAULT NULL,
`submeter_real_kw` float(11,4) DEFAULT NULL,
`submeter_total_kwh` float(11,4) DEFAULT NULL,
`submeter_kwh_demand_15` float(11,4) DEFAULT NULL,
`submeter_kw_demand_peak` float(11,4) DEFAULT NULL,
`peak_voltage` float(11,2) DEFAULT NULL,
`peak_current` float(11,2) DEFAULT NULL,
`demand` float(11,2) DEFAULT NULL,
`inst_demand` float(11,2) DEFAULT NULL,
`hist_peek_demand` float(11,2) DEFAULT NULL,
`power_factor` float(11,2) DEFAULT NULL,
`crest_factor` float(11,2) DEFAULT NULL,
`frequency` varchar(20) DEFAULT NULL,
`app_power` float(11,2) DEFAULT NULL,
`tot_app_energy` float(11,2) DEFAULT NULL,
`tot_har_dist_vol` float(11,2) DEFAULT NULL,
`tot_har_dist_curr` float(11,2) DEFAULT NULL,
`har_x_dist_v` float(11,2) DEFAULT NULL,
`har_y_dist_v` float(11,2) DEFAULT NULL,
`har_z_dist_v` float(11,2) DEFAULT NULL,
`har_x_dist_c` float(11,2) DEFAULT NULL,
`har_y_dist_c` float(11,2) DEFAULT NULL,
`har_z_dist_c` float(11,2) DEFAULT NULL,
`interval` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1136511 DEFAULT CHARSET=latin1 |
【讨论】:
【参考方案2】:要优化,添加一个复合索引:
INDEX(device_id, outlet_id, duration)
不相关的 cmets:
FLOAT(m,n)
几乎总是做错事。考虑DECIMAL(m,n)
或普通FLOAT
。
这些列真的是最优的吗?在适当的地方使用NOT NULL
。
编辑
假设您已经建立了表,您可以通过以下方式添加索引:
ALTER TABLE device_raw_usages ADD INDEX(device_id, outlet_id, duration);
此特定索引对您提供的一个 SELECT
有益。它可能对其他SELECTs
有帮助,也可能没有帮助。 Here 是一本关于如何为给定的SELECT
编写“最佳”INDEX
的简短食谱。
【讨论】:
你能在查询中使用索引并发布它吗?我是新手。我想知道你是怎么做的..我会暗示我的其他问题。以上是关于提高这个慢查询的性能的主要内容,如果未能解决你的问题,请参考以下文章
后端接口如何提高性能?从MySQLESHBASE等技术一起探讨下!