Я оптимизировал свои идеи для решения ниже:
`DROP procedure chartSelection;
DROP table chartSelectionTable;
Delimiter //
CREATE PROCEDURE chartSelection(iter int, step int, pointId int, setStart int, setStop int)
BEGIN
CREATE temporary TABLE if not exists chartSelectionTable(id int(11) NOT NULL,
pointValue double NOT NULL,ts bigint(20) NOT NULL) engine=InnoDB;
TRUNCATE TABLE chartSelectionTable;
SET @i=0;
SET @iter = iter;
SET @pointId = pointId;
chart: 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);
END IF;
insert into chartSelectionTable(
select id, pointValue,ts from (
select * from pointvalues where (
id = (select id from( select * from flex2.pointvalues as pv where pv.dataPointId=pointId order by ts limit setStart,setStop) as minval order by pointValue asc limit 0,1)
or
id = (select id from( select * from flex2.pointvalues as pv where pv.dataPointId=pointId order by ts limit setStart,setStop) as maxval order by pointValue desc limit 0,1)
)) as b
);
SET @i = @i+1;
IF @i > @iter THEN
LEAVE chart;
END IF;
END WHILE;
select * from chartSelectionTable;
drop table chartSelectionTable;
END//
delimiter ;
`
Я звоню по:
CALL chartSelection(100,90,1,0,0);
Но с Java (на уровне сервера) он вызывается:
`import java.sql.Statement;
(...)
Statement createProcedureStmt = conn.createStatement();`
`createProcedureStmt.execute( "CREATE PROCEDURE `chartSelection` "+
"(iter int, step int, pointId int, setStart int, setStop int )"+
" BEGIN "+
" TRUNCATE TABLE chartSelectionTable;"+
" SET @i=0;"+
" SET @iter = iter; "+
" SET @pointId = pointId;"+
" chart: 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);"+
" END IF;"+
" insert into chartSelectionTable("+
" select id, pointValue,ts from ("+
" select * from pointvalues where ("+
" id = (select id from( select * from flex2.pointvalues as pv where pv.dataPointId=pointId order by ts limit setStart,setStop) as minval order by pointValue asc limit 0,1)"+
" or"+
" id = (select id from( select * from flex2.pointvalues as pv where pv.dataPointId=pointId order by ts limit setStart,setStop) as maxval order by pointValue desc limit 0,1)"+
" )) as b "+
" );"+
" SET @i = @i+1;"+
" IF @i > @iter THEN"+
" LEAVE chart;"+
" END IF;"+
" END WHILE;"+
" select * from chartSelectionTable; "+
" END ");
/* Call stored procedure */
java.sql.CallableStatement stmt = conn
.prepareCall("{call chartSelection(?,?,?,0,0)}");
stmt.setInt(1, iteracje);
stmt.setInt(2, step);
stmt.setInt(3, dataPointId);`
Время оценки сокращается примерно на 50%, но все равно это слишком долго. Что изменилось:
- временная таблица вместо реальной,
- выбор только точки значения и отметки времени из всех столбцов,
способ выбора.
Как преобразовать его в решение без петель? Как выйти из лимитов и порядка?
---- ДЛЯ ПОДКЛЮЧЕНИЯ ----
1) у меня 1 000 000 записей для id = x,
2) у меня лимит = 200 записей для графика
3) Так что в Java я вычисляю - прежде чем я вызову SQL, 1 000 000 / (limit / 2) = 10 000 записей в 100 группах.
4) ОСНОВНАЯ ПРОБЛЕМА: шаг за шагом выбирайте каждую группу (на основе отметок времени) и набирайте
и max (pointValue и отметка времени) в группе.