【问题标题】: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_idoutlet_id 等定义了索引?
  • 请告诉我们SHOW CREATE TABLE device_raw_usages的输出
  • 提供表定义、MySQL 设置和最重要的EXPLAIN 的输出。 @user3065931 - LIMIT 在这里没有影响,它永远不会使选择更快 - 请阅读 LIMIT 如何在内部工作(MySQL 收集所有记录,然后丢弃从 OFFSET 开始的所有记录以获取 LIMIT 行数)。

标签: mysql query-performance


【解决方案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 的简短食谱。

    【讨论】:

    • 你能在查询中使用索引并发布它吗?我是新手。我想知道你是怎么做的..我会暗示我的其他问题。
    猜你喜欢
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 2012-04-10
    • 2017-04-12
    相关资源
    最近更新 更多