我设计了一个mysql数据库,并加载了一些数据(总共可能有10个mio行)。 我正在尝试从时间间隔重叠的两个表中获取数据。
constructor(props) {
super(props);
this.state = {
error: {
firstName: false
},
general: {
adminFirstName: "",
},
};
}
setData = () => {
const {general} = this.state;
const isValid = Object.keys(general)
.filter( key => general[key].length !== 0 ).length === Object.keys(general).length;
if (!isValid) {
Object.keys(general).map(key => {
if (general[key].length === 0) { this.setError(key); } });
} else {
// this.props.setGeneralData(general);
// this.props.nextStep();
}
console.log(isValid);
console.log(general);
};
setError = key => {
const { error } = this.state;
console.log(key);
switch (key) {
case "adminFirstName": {
this.setState({ error: { ...error, firstName: true } });
}
default:
this.setState({ error: { ...error } });
}
};
render() {
const { error, general } = this.state;
return (
<div className="block--part_75">
<Form>
{/* First name */}
<Form.Field required error={error.firstName}>
<label>First name</label>
<Input onChange={e => {
e.target.value.length !== 0
? this.setState({
error: { ...error, firstName: false },
general: {
...general,
adminFirstName: e.target.value
}
})
: this.setState({
error: { ...error, firstName: true },
general: {
...general,
adminFirstName: e.target.value
}
});
}}
placeholder="First name"
type="text"
/>
</Form.Field>
{/* First name */}
</Form>
<Button onClick={this.setData} floated="right">
Next
</Button>
</div>
);
}
不幸的是,查询花费的时间太长(我还没有完成)。
使用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
)。这会降低性能吗?如果是这样,如何设计一个更快的查询?
mysql服务器在我的笔记本电脑上(16GB RAM,CPU E3-1505M v5)。我没有对mysql设置进行任何更改。这样有用吗?
我希望在适当的时间内得到查询结果(几分钟内就可以了)。
谢谢。
答案 0 :(得分:1)
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, ...
;这没有意义,所以我忽略了它。