如何提高风数据SQL查询性能
How to improve wind data SQL query performance
我正在寻求有关如何优化(如果可能)用于读取风信息(见下文)的 SQL
查询的性能的帮助,方法是更改例如数据库结构、查询或其他?
我使用托管数据库来存储一个 table 超过 800,000 行的风信息(速度和方向)。每分钟从风速计添加新数据。使用 PHP
脚本访问数据库,该脚本创建网页以使用 Google 的可视化 API.
绘制数据
网页加载大约需要 15 秒。我在 PHP
和 Javascript
部分都添加了一些时间测量来分析代码并找到可能需要改进的地方。
我希望改进的部分是以下查询,它执行大约需要 4 秒。查询的目的是对15分钟的风速(min/max/mean)进行分组,计算这段时间测量的平均值和总和min/max。
SELECT AVG(d_mean) AS group_mean,
MAX(d_max) as group_max,
MIN(d_min) AS
group_min,
dir,
FROM_UNIXTIME(MAX(dt),'%Y-%m-%d %H:%i') AS group_dt
FROM (
SELECT @i:=@i+1,
FLOOR(@i/15) AS group_id,
CAST(mean AS DECIMAL(3,1)) AS d_mean,
CAST(min AS DECIMAL(3,1)) AS d_min,
CAST(max AS DECIMAL(3,1)) AS d_max,
dir,
UNIX_TIMESTAMP(STR_TO_DATE(dt, '%Y-%m-%d %H:%i')) AS dt
FROM table, (SELECT @i:=-1) VAR_INIT
ORDER BY id DESC
) AS T
GROUP BY group_id
LIMIT 0, 360
...
$oResult = mysql_query($sSQL);
table的结构如下:
1 ID int(11) AUTO_INCREMENT
2 mean varchar(5) utf8_general_ci
3 max varchar(5) utf8_general_ci
4 min varchar(5) utf8_general_ci
5 dt varchar(20) utf8_general_ci // Date and time
6 dir varchar(5) utf8_general_ci
使用以下设置:
- 数据库:MariaDB,5.5.42-MariaDB-1~wheezy
- 数据库客户端版本:libmysql - 5.1.66
- PHP版本:5.6
- PHP 扩展名:mysqli
我非常同意到目前为止的评论 -- 在将数据放入 table 时清理数据。
完成清理后,让我们通过执行以下操作来避免子查询...
SELECT MIN(dt) as 'Start of 15 mins',
FORMAT(AVG(mean), 1) as 'Avg wind speed',
...
FROM table
GROUP BY FLOOR(UNIX_TIMESTAMP(dt) / 900)
ORDER BY FLOOR(UNIX_TIMESTAMP(dt) / 900);
我不明白 LIMIT
的目的。我猜你想要一次几天。为此,我建议您在 FROM
和 GROUP BY
之间添加 (after cleaning)。
WHERE dt >= '2015-04-10'
AND dt < '2015-04-10' + INTERVAL 7 DAY
这将显示 7 天,从“2015-04-10”早上开始。
为了处理 800K 的 table,您肯定需要(同样, 清理后):
INDEX(dt)
要清理 800K 行,有多种方法。我建议创建一个新的 table,将数据复制进去,测试并最终交换。像...
CREATE TABLE new (
dt DATETIME,
mean FLOAT,
...
PRIMARY KEY(dt) -- assuming you have only one row per minute?
) ENGINE=InnoDB;
INSERT INTO new (dt, mean, ...)
SELECT str_to_date(...),
mean, -- I suspect that the CAST is not needed
...;
编写新的select并测试它。
现在 new
缺少较新的行。您可以重建它并希望在一分钟内完成所有内容 window,或者玩其他游戏。如果您需要帮助,请告诉我们。
我正在寻求有关如何优化(如果可能)用于读取风信息(见下文)的 SQL
查询的性能的帮助,方法是更改例如数据库结构、查询或其他?
我使用托管数据库来存储一个 table 超过 800,000 行的风信息(速度和方向)。每分钟从风速计添加新数据。使用 PHP
脚本访问数据库,该脚本创建网页以使用 Google 的可视化 API.
网页加载大约需要 15 秒。我在 PHP
和 Javascript
部分都添加了一些时间测量来分析代码并找到可能需要改进的地方。
我希望改进的部分是以下查询,它执行大约需要 4 秒。查询的目的是对15分钟的风速(min/max/mean)进行分组,计算这段时间测量的平均值和总和min/max。
SELECT AVG(d_mean) AS group_mean,
MAX(d_max) as group_max,
MIN(d_min) AS
group_min,
dir,
FROM_UNIXTIME(MAX(dt),'%Y-%m-%d %H:%i') AS group_dt
FROM (
SELECT @i:=@i+1,
FLOOR(@i/15) AS group_id,
CAST(mean AS DECIMAL(3,1)) AS d_mean,
CAST(min AS DECIMAL(3,1)) AS d_min,
CAST(max AS DECIMAL(3,1)) AS d_max,
dir,
UNIX_TIMESTAMP(STR_TO_DATE(dt, '%Y-%m-%d %H:%i')) AS dt
FROM table, (SELECT @i:=-1) VAR_INIT
ORDER BY id DESC
) AS T
GROUP BY group_id
LIMIT 0, 360
...
$oResult = mysql_query($sSQL);
table的结构如下:
1 ID int(11) AUTO_INCREMENT
2 mean varchar(5) utf8_general_ci
3 max varchar(5) utf8_general_ci
4 min varchar(5) utf8_general_ci
5 dt varchar(20) utf8_general_ci // Date and time
6 dir varchar(5) utf8_general_ci
使用以下设置:
- 数据库:MariaDB,5.5.42-MariaDB-1~wheezy
- 数据库客户端版本:libmysql - 5.1.66
- PHP版本:5.6
- PHP 扩展名:mysqli
我非常同意到目前为止的评论 -- 在将数据放入 table 时清理数据。
完成清理后,让我们通过执行以下操作来避免子查询...
SELECT MIN(dt) as 'Start of 15 mins',
FORMAT(AVG(mean), 1) as 'Avg wind speed',
...
FROM table
GROUP BY FLOOR(UNIX_TIMESTAMP(dt) / 900)
ORDER BY FLOOR(UNIX_TIMESTAMP(dt) / 900);
我不明白 LIMIT
的目的。我猜你想要一次几天。为此,我建议您在 FROM
和 GROUP BY
之间添加 (after cleaning)。
WHERE dt >= '2015-04-10'
AND dt < '2015-04-10' + INTERVAL 7 DAY
这将显示 7 天,从“2015-04-10”早上开始。
为了处理 800K 的 table,您肯定需要(同样, 清理后):
INDEX(dt)
要清理 800K 行,有多种方法。我建议创建一个新的 table,将数据复制进去,测试并最终交换。像...
CREATE TABLE new (
dt DATETIME,
mean FLOAT,
...
PRIMARY KEY(dt) -- assuming you have only one row per minute?
) ENGINE=InnoDB;
INSERT INTO new (dt, mean, ...)
SELECT str_to_date(...),
mean, -- I suspect that the CAST is not needed
...;
编写新的select并测试它。
现在 new
缺少较新的行。您可以重建它并希望在一分钟内完成所有内容 window,或者玩其他游戏。如果您需要帮助,请告诉我们。