Mysql Сделать хранимую процедуру быстрее
Я в sql не сильно разбираюсь, написал такую хранимку. Хорошо бы ее сделать быстрее и эффективнее, если это возможно.
Есть числа в базе данных. Нужно рассчитать максимальную серию не выпадения.
Пример
Числа: 0 0 0 0 1 2 1 1 2 3 4 5 5 6 5 6 6 6 1
Макс серия не выпадения
0-15
1-10
2-10
3-9
4-10
5-11
6-13
Логика рассчета:
К примеру, 0 - мы видим что он выпадает 4 раза подряд, и после не выпадает - значит считаем количество с последнего выпадения нуля и до конца.
К примеру 4 - мы видим что количество до первого выпадения 4 больше, чем количество цифр после 4 - значит записываем первое количество.
Таблица:
id bigint
result int
date datetime
Используется mysql
Сама хранимка ниже.
И вопрос такой, где лучше считать, на стороне SQL или PHP. Важна скорость расчетов
DELIMITER $
CREATE DEFINER=`root`@`localhost` FUNCTION `CalculateStreakOfNonDropouts`(`number` INT, `beginDate` DATETIME, `endDate` DATETIME) RETURNS int(11)
BEGIN
DECLARE dates INT;
DECLARE currentIndex INT;
DECLARE nextIndex INT;
DECLARE maxSeries INT;
DECLARE tmpSeries INT;
DECLARE firstIteration INT;
SET firstIteration = 0;
SET tmpSeries = 0;
SET currentIndex = -1;
SET nextIndex = 0;
SET maxSeries = 0;
SET dates = (SELECT COUNT(`date`) FROM `rolls` WHERE `result`=number AND `date`>=(SELECT beginDate) AND `date`
IF dates=0 THEN
SET maxSeries = (SELECT COUNT(`result`) FROM `rolls` WHERE `date`>=(SELECT beginDate) AND `date`
ELSEIF dates=1 THEN
SET tmpSeries = (SELECT COUNT(`result`) FROM `rolls` WHERE `result`!=number and `date`>=(SELECT `date` FROM `rolls` WHERE `result`=number AND `date`>=(SELECT beginDate) AND `date`
SET maxSeries = (SELECT COUNT(`result`) FROM `rolls` WHERE `result`!=number and `date`=(SELECT beginDate) AND `date`=(SELECT beginDate));
IF tmpSeries>maxSeries THEN
SET maxSeries=tmpSeries;
END IF;
ELSE
loop_1: WHILE currentIndex
IF firstIteration=0 THEN
SET maxSeries=(SELECT COUNT(`result`) FROM `rolls` WHERE `result`!=number AND `date` BETWEEN (SELECT beginDate) AND (SELECT `date` FROM `rolls` WHERE `result`=number AND `date`>=(SELECT beginDate) AND `date`
SET firstIteration=1;
END IF;
SET currentIndex=currentIndex+1;
SET nextIndex=nextIndex+1;
IF nextIndex=dates THEN
set tmpSeries=(SELECT COUNT(`result`) FROM `rolls` WHERE `result`!=number AND `date` BETWEEN (SELECT `date` FROM `rolls` WHERE `result`=number AND `date`>=(SELECT beginDate) AND `date`
ELSE
SET tmpSeries=(SELECT COUNT(`result`) FROM `rolls` WHERE `result`!=number AND `date` BETWEEN (SELECT `date` FROM `rolls` WHERE `result`=number AND `date`>=(SELECT beginDate) AND `date`=(SELECT beginDate) AND `date`
END IF;
IF tmpSeries>maxSeries THEN
SET maxSeries=tmpSeries;
END IF;
END WHILE;
END IF;
RETURN maxSeries;
END$
DELIMITER ;