我有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`);
在地图上,我通过日历调用日期,以通过这个INNER JOIN查询(在示例中输入日期)来搜索archive2表上的数据:
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%'
一切正常,但是即使查询执行时间似乎还可以(大约0.5s / 1.0s),显示结果所需的时间却确实很慢(4/5秒)。 我试图在PHPMyadmin上执行查询,结果是相同的。执行时间很快,但是显示结果的时间却非常缓慢。
EXPLAIN查询结果
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
要测试的网址:https://retemeteo.lineameteo.it/index_archivio.php
更新:如果我从“ IDStazione”中删除索引,查询将正常进行。但是以这种方式,我失去了其他查询的所有优势和速度...如果我在该字段上添加索引,为什么只有该查询变慢?
答案 0 :(得分:3)
在您的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
)。>
答案 1 :(得分:1)
(解决DATE是主要的性能解决方案;这是一个不太关键的问题。)
表太大了。大小会影响磁盘空间,并在一定程度上影响速度。
您有1743个工作站,但是数据类型是32位(4字节)数字(INT
)。 SMALLINT UNSIGNED
将允许64K电台,并且仅使用2个字节。
那里真的真的很热吗?像999999999.9度? DECIMAL(10.1)
占用5个字节; DECIMAL(4,1)
仅需3个,最多允许999.9度。 DECIMAL(3,1)
的最大值为99.9,仅占用2个字节。
在大表中“ localita
varchar(100)”是做什么的?似乎您可以在需要时JOIN
进入车站表?删除该表可能会使表的大小减半。