我设置了一个每小时运行一次的简单事件,并添加如下记录:
ON SCHEDULE EVERY 1 HOUR STARTS '2015-01-01 00:00:00'
DO
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a INT;
DECLARE cursor_1 CURSOR FOR SELECT item_id FROM item WHERE NOW()>expiration_date AND has_expired = 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cursor_1;
read_loop: LOOP
FETCH cursor_1 INTO a;
IF done THEN
LEAVE read_loop;
END IF;
UPDATE item SET has_expired=1 WHERE quote_id=a;
INSERT INTO item_log (item_id, message) VALUES (a, 'Item is now expired');
END LOOP;
END
这个东西每天运行24次并且按预期工作,但是,还有另一个想法是动态创建事件并将它们附加给定记录,例如
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK
DO
BEGIN
UPDATE item SET has_expired=1 WHERE item_id=232;
INSERT INTO item_log (item_id, message) VALUES (232, 'Item is now expired');
END
当然上面会有不同的interval和id值,但这意味着可能有1000或数万个事件。
现在,这会有问题吗?限制和性能明智吗? 我可以想象,如果没有记录,或者只有少数记录创建一个月,那么第一种方法将不断运行。但是,如果一小时内添加的项目很少,则意味着数据库可以达到数千个一次性事件。这不会引起自身的问题吗?
答案 0 :(得分:0)
你想以100%的速度跑吗?摆脱它。相反,SELECTs包含条款AND (expiration_date < NOW())
好的,所以你问了代码。以下是一些评论:
UPDATE和INSERT需要处于事务中。
SELECT需要FOR UPDATE,也应该在事务中。但这并不重要,因为除非你改变expiration_date,否则它永远不会重要。
游标很糟糕,表现明智。选择100行进行清除,然后运行一个UPDATE和一个INSERT。
除非您的索引以expiration_date开头,否则扫描表中的此标志将是一个缓慢的“表扫描”。