如何提高风数据SQL查询性能

How to improve wind data SQL query performance

我正在寻求有关如何优化(如果可能)用于读取风信息(见下文)的 SQL 查询的性能的帮助,方法是更改​​例如数据库结构、查询或其他?

我使用托管数据库来存储一个 table 超过 800,000 行的风信息(速度和方向)。每分钟从风速计添加新数据。使用 PHP 脚本访问数据库,该脚本创建网页以使用 Google 的可视化 API.

绘制数据

网页加载大约需要 15 秒。我在 PHPJavascript 部分都添加了一些时间测量来分析代码并找到可能需要改进的地方。

我希望改进的部分是以下查询,它执行大约需要 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

使用以下设置:

我非常同意到目前为止的评论 -- 在将数据放入 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 的目的。我猜你想要一次几天。为此,我建议您在 FROMGROUP 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,或者玩其他游戏。如果您需要帮助,请告诉我们。