Добрый день.
Есть таблица следующего формата
CREATE TABLE `linestatuslog` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`line` CHAR(4) NULL DEFAULT NULL,
`status` CHAR(4) NULL DEFAULT NULL,
`user` VARCHAR(45) NULL DEFAULT NULL,
`startDate` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `line_idx` (`line`),
INDEX `status_idx` (`status`),
INDEX `user_idx` (`user`),
INDEX `startDate_idx` (`startDate`)
)
В таблице ведётся простой лог, добавляются данные по такому принципу: какой
status
был установлен для
line
и
startDate
когда. Стоит отметить, что количество
line
и
status
ограничено — около 10-15 разных наименований. Всего записей в таблице около ста тысяч.
Появилась потребность добавить поле
endDate
, в котором хотелось бы получить дату окончания конкретного статуса для конкретной линии. Датой окончания положено считать наличие следующей записи для этой же линии, но уже с другим статусом.
В общем, алгоритмически это несложная задача и она, в принципе, решается хранимой процедурой:
BEGIN
DECLARE rowCount INT;
DECLARE curRow INT;
DECLARE logId INT;
DECLARE lineName VARCHAR(4);
DECLARE _startDate DATETIME;
DECLARE _endDate DATETIME;
SET curRow=1;
myLoop: WHILE (curRow<1001) DO
SET curRow=curRow+1;
SET logId=(select id from linestatuslog where endDate is null order by startDate asc limit 1);
set lineName=(select line from linestatuslog where id=logId);
set _startDate=(select startDate from linestatuslog where id=logId);
set _endDate=(select startDate from linestatuslog where line=lineName and startDate>_startDate order by startDate asc limit 1);
IF (_endDate is null) THEN
set _endDate='2016-01-01 00:00:00';
END IF;
UPDATE linestatuslog set endDate=_endDate where id=logId;
END WHILE myLoop;
END
Как видно из кода выше, цикл ограничен только 1000 проходами, потому что даже эта 1000 работает достаточно долго (около 4х минут).
Вопрос чисто академический — как это ускорить? И что можно почитать для понимания таких вещей? Задача вроде как была решена, но долго и неэффективно, а поскольку в SQL я не силён, возник такой вопрос.