Mysql JOIN 查询明显慢

标签 mysql database inner-join query-performance

我有 2 个表。第一个称为 stazioni,我在其中存储来自某个气象站的实时天气数据,第二个称为 archivio2,其中存储存档的日期数据。这两个表有共同的 ID 站数据(stazioni 上的 ID,archvio2 上的 IDStazione)。

stazioni(1,743 行)

CREATE TABLE `stazioni` (
  `ID` int(10) NOT NULL,
  `user` varchar(100) NOT NULL,
  `nome` varchar(100) NOT NULL,
  `email` varchar(50) NOT NULL,
  `localita` varchar(100) NOT NULL,
  `provincia` varchar(50) NOT NULL,
  `regione` varchar(50) NOT NULL,
  `altitudine` int(10) NOT NULL,
  `stazione` varchar(100) NOT NULL,
  `schermo` varchar(50) NOT NULL,
  `installazione` varchar(50) NOT NULL,
  `ubicazione` varchar(50) NOT NULL,
  `immagine` varchar(100) NOT NULL,
  `lat` double NOT NULL,
  `longi` double NOT NULL,
  `file` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `temperatura` decimal(10,1) DEFAULT NULL,
  `umidita` decimal(10,1) DEFAULT NULL,
  `pressione` decimal(10,1) DEFAULT NULL,
  `vento` decimal(10,1) DEFAULT NULL,
  `vento_direzione` decimal(10,1) DEFAULT NULL,
  `raffica` decimal(10,1) DEFAULT NULL,
  `pioggia` decimal(10,1) DEFAULT NULL,
  `rate` decimal(10,1) DEFAULT NULL,
  `minima` decimal(10,1) DEFAULT NULL,
  `massima` decimal(10,1) DEFAULT NULL,
  `orario` varchar(16) DEFAULT NULL,
  `online` int(1) NOT NULL DEFAULT '0',
  `tipo` int(1) NOT NULL DEFAULT '0',
  `webcam` varchar(255) DEFAULT NULL,
  `webcam2` varchar(255) DEFAULT NULL,
  `condizioni` varchar(255) DEFAULT NULL,
  `Data2` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

archivio2(2,127,347 行)

CREATE TABLE `archivio2` (
  `ID` int(10) NOT NULL,
  `IDStazione` int(4) NOT NULL DEFAULT '0',
  `localita` varchar(100) NOT NULL,
  `temp_media` decimal(10,1) DEFAULT NULL,
  `temp_minima` decimal(10,1) DEFAULT NULL,
  `temp_massima` decimal(10,1) DEFAULT NULL,
  `pioggia` decimal(10,1) DEFAULT NULL,
  `pressione` decimal(10,1) DEFAULT NULL,
  `vento` decimal(10,1) DEFAULT NULL,
  `raffica` decimal(10,1) DEFAULT NULL,
  `records` int(10) DEFAULT NULL,
  `Data2` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我设置的索引

-- Indexes for table `archivio2`
--
ALTER TABLE `archivio2`
  ADD PRIMARY KEY (`ID`),
  ADD KEY `IDStazione` (`IDStazione`),
  ADD KEY `Data2` (`Data2`);

-- Indexes for table `stazioni`
--
ALTER TABLE `stazioni`
  ADD PRIMARY KEY (`ID`),
  ADD KEY `Tipo` (`Tipo`);
ALTER TABLE `stazioni` ADD FULLTEXT KEY `localita` (`localita`);

在 map 上,我通过日历调用日期来搜索 archive2 表上的数据,通过这个 INNER JOIN 查询(​​我放了一个示例日期):

SELECT *, c.pioggia AS rain, c.raffica AS raff, c.vento AS wind, c.pressione AS press
FROM stazioni as o
INNER JOIN archivio2 as c ON o.ID = c.IDStazione
WHERE c.Data2 LIKE '2019-01-01%'

一切正常,但显示结果所需的时间真的很慢(4/5 秒),即使查询执行时间似乎还可以(大约 0.5s/1.0s)。 我尝试在 PHPMyadmin 上执行查询,结果是一样的。执行时间很快,但显示结果的时间非常慢。

解释查询结果

id  select_type table   type    possible_keys       key         key_len ref                 rows    Extra
1   SIMPLE      o       ALL     PRIMARY,ID          NULL        NULL    NULL                1743    NULL    
1   SIMPLE      c       ref     IDStazione,Data2    IDStazione  4       sccavzuq_rete.o.ID  1141    Using where 

更新:如果我从“IDStazione”中删除索引,查询就会正常进行。但是这样一来,我就失去了其他查询的所有优势和速度……如果我在那个字段上放置索引,为什么只有那个查询变慢了?

最佳答案

在你的 WHERE 子句中

WHERE c.Data2 LIKE '2019-01-01%'

Data2 的值必须转换为字符串。没有索引可以用于该条件。

改成

WHERE c.Data2 >= '2019-01-01' AND c.Data2 < '2019-01-01' + INTERVAL 1 DAY

这样引擎应该能够使用 (Data2) 上的索引。

现在检查 EXPLAIN 结果。我希望,表顺序被交换并且 key 列将显示 Data2(对于 c)和 ID(对于 o)。

关于Mysql JOIN 查询明显慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56197716/

相关文章:

postgresql - Postgres 嵌套循环顺序

PHP如何显示用户数据

MYSQL - 将数据复制到另一个数据库

php - mysql:包含在 mysql 查询中

php - 如何在 PHP 中转换 MySQL INNER JOIN 结果?

mysql - 使用 INNER JOIN 从一个表中获取所有字段?

mysql - 加入条件的顺序重要吗?

mysql - 如何更改 wordpress 搜索栏中的搜索操作?

c# - 在 C# 项目中添加 MySQL 库

java - 如何使用索引使Web应用程序中的数据库访问更快?