我设计了一个mysql数据库并加载了一些数据(总共可能有1000万行)。我试图从两个时间间隔重叠的表中获取数据。
SELECT
cd.ParameterID,
intervals.TimeStamp,
intervals.GreenHouseID,
intervals.TargetParam,
intervals.ProductionID
FROM
(
SELECT
pd.TimeStamp,
p.GreenHouseID,
pd.ParameterID AS TargetParam,
pd.ProductionID
FROM
Production p INNER JOIN
ProductionData pd ON pd.ProductionID=p.ID
GROUP BY
pd.TimeStamp, p.GreenHouseID
) AS intervals,
ClimateData cd
WHERE
DATE_FORMAT(intervals.TimeStamp,'%Y-%m-%d') = DATE_FORMAT(cd.Time_stamp,'%Y-%m-%d') AND
cd.GreenHouseID = intervals.GreenHouseID
GROUP BY
intervals.ProductionID, intervals.TargetParam
不幸的是,查询花费的时间太长(我还没有看到它完成)。
当我使用 EXPLAIN
我得到以下结果:
|id|select_type|table |partitions|type |possible_keys|key |key_len|ref |rows|filtered|Extra
|1|PRIMARY |<derived2>|NULL |ALL |NULL |NULL |NULL |NULL | 416| 100.00|Using where Using temporary
|1|PRIMARY |cd |NULL |ref |cd_ghid_idx |cd_ghid_idx |4 |intervals.GreenHouseID|1660| 100.00|Using where
|2|DERIVED |p |NULL |index|PRIMARY |pr_gh_fk_idx |5 |NULL | 13| 100.00|Using index Using temporary
|2|DERIVED |pd |NULL |ref |pd_pr_fk_idx |pd_pr_fk_idx |5 |ghdb.p.ID | 32| 100.00|NULL
我相信我把索引放在所有相关的列上,以确保快速查询。我设计的查询使用一个临时表( intervals
)然而。这是在贬低表演吗?如果是这样,如何设计一个更快的查询?
mysql服务器在我的笔记本电脑上(16GBRAM,cpu e3-1505MV5)。我没有对mysql设置做任何更改。那有用吗?
我想在适当的时间查询结果(在几分钟内就可以了)。
谢谢您。
1条答案
按热度按时间inb24sb21#
请提供
SHOW CREATE TABLE
对于每个表,包括临时表。temp表上似乎只有一列索引?
临时性和永久性应该在性能上没有区别。但是,创建temp表的额外步骤可能会付出代价。
说
NOT NULL
在适当的情况下。在函数调用中隐藏列(
DATE_FORMAT
在您的例子中)防止使用索引—因此ALL
.您不能“调整您的方式以解决性能问题”,因此我将不讨论调整,而只是询问
innodb_buffer_pool_size
.请不要使用“逗号连接”;相反,使用
JOIN .. ON ..
主要性能问题如下:它需要看起来更像
既然你要努力建造
intervals
在飞行中,有一列只包含日期。你也可以通过DATE(...)
而不是DATE_FORMAT(...)
.由于您正在计算其中一个日期,请更改
pd.TimeStamp
到那么,
你还需要把这个“综合”索引放在一起
intervals
:我明白了
GROUP BY pd.TimeStamp, ...
; 这没有道理,所以我忽略它。