MySQL事件 - 性能和限制

时间:2015-01-16 14:31:27

标签: mysql performance events

我设置了一个每小时运行一次的简单事件,并添加如下记录:

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或数万个事件。

现在,这会有问题吗?限制和性能明智吗? 我可以想象,如果没有记录,或者只有少数记录创建一个月,那么第一种方法将不断运行。但是,如果一小时内添加的项目很少,则意味着数据库可以达到数千个一次性事件。这不会引起自身的问题吗?

1 个答案:

答案 0 :(得分:0)

你想以100%的速度跑吗?摆脱它。相反,SELECTs包含条款AND (expiration_date < NOW())

好的,所以你问了代码。以下是一些评论:

UPDATE和INSERT需要处于事务中。

SELECT需要FOR UPDATE,也应该在事务中。但这并不重要,因为除非你改变expiration_date,否则它永远不会重要。

游标很糟糕,表现明智。选择100行进行清除,然后运行一个UPDATE和一个INSERT。

除非您的索引以expiration_date开头,否则扫描表中的此标志将是一个缓慢的“表扫描”。