如何更快地查询我的 mysql table?
How to make faster queries on my mysql table?
我有以下table
如您所见,它有 1868155 行。我正在尝试制作实时图表,但这是不可能的,因为几乎所有查询都持续 1 或 2 秒。
例如这个查询
SELECT sensor.nombre, temperatura.temperatura
FROM sensor, temperatura
WHERE sensor.id = temperatura.idsensor
ORDER BY temperatura.fecha DESC, idsensor ASC
LIMIT 4
应该显示这个
我已经尝试了一切,使用索引(可能不正确),只使用我需要的字段而不是 *,等等,但结果是一样的!
这些是 table 的索引。
查询说明
已编辑
这是执行后查询的解释
ALTER TABLE temperatura
ADD INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
并为查询使用内连接语法
SELECT s.nombre, t.temperatura
FROM sensor s
INNER JOIN temperatura t
ON s.id = t.idsensor
ORDER BY t.fecha DESC, t.idsensor ASC
LIMIT 4
这是我的全部传感器table
尝试以下操作:
ALTER TABLE temperatura
ADD INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
我还推荐使用现代连接语法:
SELECT s.nombre, t.temperatura
FROM sensor s
INNER JOIN temperatura t
ON s.id = t.idsensor
ORDER BY t.fecha DESC, t.idsensor ASC
LIMIT 4
做完以上修改后,如果性能还是不够好,再报告一下EXPLAIN。
尝试#2
仔细查看您尝试执行的操作后,我相信下一个查询可能更有效:
SELECT
s.nombre, t.temperatura
FROM temperatura t
LEFT OUTER JOIN temperatura later_t
ON later_t.idsensor = t.idsensor
AND later_t.fecha > t.fecha
INNER JOIN sensor s
ON s.id = t.idsensor
WHERE later_t.idsensor IS NULL
ORDER BY t.idsensor ASC
您也可以试试:
SELECT
s.nombre, t.temperatura
FROM temperatura t
INNER JOIN (
SELECT
t.idsensor,
MAX(t.fecha) AS fecha
FROM temperatura t
GROUP BY t.idsensor
) max_fecha
ON max_fecha.idsensor = t.idsensor
AND max_fecha.fecha > t.fecha
INNER JOIN sensor s
ON s.id = t.idsensor
ORDER BY t.idsensor ASC
根据我的经验,如果您要查找最近的记录,上述两个查询之一都可以。哪种效果最好取决于多种因素,因此请同时尝试。
让我知道它们的表现如何,以及它们是否仍能为您提供所需的数据。此外,任何查询您 运行、运行 至少 3 次,并报告所有 3 次。这将有助于准确衡量给定查询的速度,因为各种外部因素都会影响查询的速度。
无法优化 ASC
和 DESC
的混合,如
ORDER BY t.fecha DESC, t.idsensor ASC
您尝试了覆盖索引:
INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
不过,这个覆盖索引可能更好:
INDEX `sensor_temp` (`fecha`,`idsensor`,`temperatura`)
然后,如果您愿意以不同的顺序获取传感器,请使用
ORDER BY t.fecha DESC, t.idsensor DESC
最后 最多 4 个传感器 fecha
:
sensor: PRIMARY KEY(id)
tempuratura: INDEX(fecha, idsensor, tempuratura)
SELECT
( SELECT nombre FROM sensor WHERE id = t.idsensor ) AS nombre,
t.temperatura
FROM
( SELECT MAX(fecha) AS max_fecha FROM tempuratura ) AS z
JOIN temperatura AS t ON t.fecha = z.max_fecha
ORDER BY t.idsensor ASC
LIMIT 4;
我有以下table
如您所见,它有 1868155 行。我正在尝试制作实时图表,但这是不可能的,因为几乎所有查询都持续 1 或 2 秒。
例如这个查询
SELECT sensor.nombre, temperatura.temperatura
FROM sensor, temperatura
WHERE sensor.id = temperatura.idsensor
ORDER BY temperatura.fecha DESC, idsensor ASC
LIMIT 4
应该显示这个
我已经尝试了一切,使用索引(可能不正确),只使用我需要的字段而不是 *,等等,但结果是一样的!
这些是 table 的索引。
查询说明
已编辑
ALTER TABLE temperatura
ADD INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
并为查询使用内连接语法
SELECT s.nombre, t.temperatura
FROM sensor s
INNER JOIN temperatura t
ON s.id = t.idsensor
ORDER BY t.fecha DESC, t.idsensor ASC
LIMIT 4
这是我的全部传感器table
尝试以下操作:
ALTER TABLE temperatura
ADD INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
我还推荐使用现代连接语法:
SELECT s.nombre, t.temperatura
FROM sensor s
INNER JOIN temperatura t
ON s.id = t.idsensor
ORDER BY t.fecha DESC, t.idsensor ASC
LIMIT 4
做完以上修改后,如果性能还是不够好,再报告一下EXPLAIN。
尝试#2
仔细查看您尝试执行的操作后,我相信下一个查询可能更有效:
SELECT
s.nombre, t.temperatura
FROM temperatura t
LEFT OUTER JOIN temperatura later_t
ON later_t.idsensor = t.idsensor
AND later_t.fecha > t.fecha
INNER JOIN sensor s
ON s.id = t.idsensor
WHERE later_t.idsensor IS NULL
ORDER BY t.idsensor ASC
您也可以试试:
SELECT
s.nombre, t.temperatura
FROM temperatura t
INNER JOIN (
SELECT
t.idsensor,
MAX(t.fecha) AS fecha
FROM temperatura t
GROUP BY t.idsensor
) max_fecha
ON max_fecha.idsensor = t.idsensor
AND max_fecha.fecha > t.fecha
INNER JOIN sensor s
ON s.id = t.idsensor
ORDER BY t.idsensor ASC
根据我的经验,如果您要查找最近的记录,上述两个查询之一都可以。哪种效果最好取决于多种因素,因此请同时尝试。
让我知道它们的表现如何,以及它们是否仍能为您提供所需的数据。此外,任何查询您 运行、运行 至少 3 次,并报告所有 3 次。这将有助于准确衡量给定查询的速度,因为各种外部因素都会影响查询的速度。
无法优化 ASC
和 DESC
的混合,如
ORDER BY t.fecha DESC, t.idsensor ASC
您尝试了覆盖索引:
INDEX `sensor_temp` (`idsensor`,`fecha`,`temperatura`)
不过,这个覆盖索引可能更好:
INDEX `sensor_temp` (`fecha`,`idsensor`,`temperatura`)
然后,如果您愿意以不同的顺序获取传感器,请使用
ORDER BY t.fecha DESC, t.idsensor DESC
最后 最多 4 个传感器 fecha
:
sensor: PRIMARY KEY(id)
tempuratura: INDEX(fecha, idsensor, tempuratura)
SELECT
( SELECT nombre FROM sensor WHERE id = t.idsensor ) AS nombre,
t.temperatura
FROM
( SELECT MAX(fecha) AS max_fecha FROM tempuratura ) AS z
JOIN temperatura AS t ON t.fecha = z.max_fecha
ORDER BY t.idsensor ASC
LIMIT 4;