我需要运行 MYSQL 程序,该程序将从表 pointValues 中选择单点的时间序列记录。当然,记录的数量可能很大——所以我只需要选择其中的 200 个(限制)来绘制图表。我决定按照以下逻辑划分所有记录:
a) 记录/(limit/2) -> 每个组中的行数
b) 从 a) 中定义的每个组中获取最小值和最大值。
我在高性能查询方面没有太多经验,所以我需要一些帮助来提高这个过程的性能。
CREATE TABLE secChart ( id int(11) NOT NULL, dataPointId int(11) NOT NULL, dataType int(11), pointValue DOUBLE NOT NULL, ts bigint(20) NOT NULL ) ENGINE=InnoDB; DROP PROCEDURE dataChart; DROP PROCEDURE IF EXISTS dataChart; DELIMITER // CREATE PROCEDURE dataChart(iter int, step int, pointId int, setStart int,
setStop int) BEGIN TRUNCATE TABLE secChart;
SET @i = 0; SET @iter = iter; SET @pointId = pointId; myLoop: WHILE (@i < @iter) DO IF @i = 0 THEN SET setStart = 0; SET setStop = step-1; END IF; IF @i > 0 THEN SET setStart = @i * step; SET setStop = setStart + (step-1); SET @start = setStart; SET @stop = setStop; END IF; ** INSERT INTO secChart (SELECT * FROM pointvalues WHERE dataPointId = @pointId AND (pointValue = (SELECT MIN(pointValue) FROM (SELECT * FROM flex2.pointvalues WHERE dataPointId = @pointId ORDER BY id ASC LIMIT setStart, setStop) AS b) OR pointValue = (SELECT MAX(pointValue) FROM (SELECT * FROM flex2.pointvalues WHERE dataPointId = @pointId ORDER BY id ASC LIMIT setStart, setStop) AS b2)) ORDER BY id LIMIT 0, 2);** SET @i = @i + 1; IF @i > @iter THEN LEAVE myLoop; END IF; END WHILE; END// DELIMITER ; CALL dataChart(100, 80, 1, 0, 0);
对于近 15 000 条记录,需要 158 秒...
我测试的另一个选择:
INSERT INTO idx
VALUES(@start, @stop , @i, step);
INSERT INTO stt
(SELECT *
FROM
((SELECT *
FROM
(SELECT id, pointValue, ts
FROM flex2.pointvalues AS pv
WHERE pv.dataPointId = 1
ORDER BY id
LIMIT setStart, setStop) AS minval
ORDER BY pointValue DESC
LIMIT 0, 1)
UNION
(SELECT *
FROM
(SELECT id, pointValue, ts
FROM flex2.pointvalues AS pv
WHERE pv.dataPointId = 1
ORDER BY id
LIMIT setStart, setStop) AS maxval
ORDER BY pointValue ASC
LIMIT 0, 1)) AS selectScore);
对于将近 15 000 条记录,它需要 58 秒 - 更快但不够快。
第三个想法是选择 n 行(例如从 12 000 行中选择 200 行)
SELECT COUNT(*)
FROM flex2.pointvalues
WHERE dataPointId = 1
AND id IN (SELECT id
FROM flex2.pointvalues
WHERE dataPointId = 1
AND id BETWEEN
(SELECT MIN(id) FROM flex2.pointvalues
WHERE dataPointId = 1) AND
(SELECT MAX(id) FROM flex2.pointvalues
WHERE dataPointId = 1))
AND id % 10 = 0;
最好的办法是修复想法 2 的性能。请帮忙!