优化查询[减去两个特定的行Mysql]

时间:2017-10-29 08:48:17

标签: mysql optimization

SELECT (a.t_avg - b.t_avg) as t_diff, 
        (a.prcp - b.prcp) as prcp_diff, 
        a.county as county 
FROM (SELECT * FROM weather WHERE ob_date='2016-01-01') a 
JOIN (SELECT * FROM weather WHERE ob_date='2016-01-02') b 
  ON a.station_name = b.station_name 
GROUP BY a.county

对于任何两个日期,我都希望温度和降水的差异有效。目前,查询平均需要1.2分钟

我的表结构是

+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |

+--------------+-------------+------+-----+---------+----------------+
| id           | int(11)     | NO   | PRI | NULL    | auto_increment |
| station_name | varchar(20) | NO   | MUL | NULL    |                |
| t_max        | float       | NO   |     | NULL    |                |
| t_min        | float       | NO   |     | NULL    |                |
| t_avg        | float       | NO   |     | NULL    |                |
| prcp         | float       | NO   |     | NULL    |                |
| geo_lat      | float(10,4) | NO   | MUL | NULL    |                |
| geo_long     | float(10,4) | NO   |     | NULL    |                |
| ob_date      | date        | NO   | MUL | NULL    |                |
| county       | varchar(5)  | YES  | MUL | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

解释的输出 Output of Explain statment

1 个答案:

答案 0 :(得分:0)

除非您需要,否则请勿使用“派生表”。这是重新制定它的方法:

SELECT ...
    FROM weather AS a
    JOIN weather AS b  USING(station_name)
    WHERE a.ob_date='2016-01-01'
      AND b.ob_date='2016-01-01'
    GROUP BY ...

您还应该INDEX(ob_date, station_name)

countrylat等,因为这不是给定电台的每次更改,对吗?然后制作一个单独的表格来描述这些电台。

CREATE TABLE Stations (
    station_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    station_name ...,
    lat, lng, country
    PRIMARY KEY station_id
  ) ENGINE=InnoDB;

然后你的主表不那么笨重(因此有点快):

CREATE TABLE Readings (
    station_id MEDIUMINT UNSIGNED NOT NULL,
    ob_date DATE NOT NULL,
    t_min FLOAT NOT NULL,
    t_avg FLOAT NOT NULL,
    prcp  FLOAT NOT NULL,
    PRIMARY KEY(ob_date, station_id),
    INDEX(station_id, ob_date)

ob_date, station_id是唯一的,对吗?

(您是否需要帮助将当前架构转换为新架构?您是否需要其他JOIN来获取国家/地区的帮助?)

(请勿使用DESCRIBE SHOW CREATE TABLE描述性较差。)