我设计了一个mysql数据库并加载了一些数据(总共可能有10个行)。我试图从时间间隔重叠的两个表中获取数据。
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服务器在我的笔记本电脑上(16GB RAM,CPU E3-1505M v5)。我没有对mysql设置进行任何更改。这会有用吗?
我希望在适当的时间内查询结果(在几分钟内就行了)。
谢谢。
SHOW CREATE TABLE
,包括临时表。NOT NULL
。DATE_FORMAT
)会阻止使用索引 - 因此ALL
。innodb_buffer_pool_size
的价值之外,我不会解决调整问题。JOIN .. ON ..
主要性能问题在于:
WHERE DATE_FORMAT(intervals.TimeStamp,'%Y-%m-%d') =
DATE_FORMAT(cd.Time_stamp,'%Y-%m-%d')
AND cd.GreenHouseID = intervals.GreenHouseID
它需要看起来更像
WHERE intervals.TimeStamp ...
AND cd.GreenHouseID = intervals.GreenHouseID
由于您要动态构建intervals
,请使用仅包含日期的列。你也可以通过DATE(...)
而不是DATE_FORMAT(...)
来计算它。
由于您正在计算其中一个日期,请将pd.TimeStamp
更改为
DATE(pd.TimeStamp) AS TS_Date
然后,
WHERE intervals.TimeStamp >= cd.TS_Date
AND intervals.TimeStamp < cd.TS_Date + INTERVAL 1 DAY
AND intervals.GreenHouseID = cd.GreenHouseID
您还需要与intervals
上的这个“复合”索引一起使用:
INDEX(GreenHouseID, TimeStamp) -- in this order
遗留的错误:我看到GROUP BY pd.TimeStamp, ...
;这没有意义,所以我无视它。