mysql - 有很多事件是一个好习惯吗?

时间:2017-12-09 14:42:36

标签: mysql datetime scheduled-tasks

我有一张表 tblMatch

+---------+---------------------+------------------+-----------+ 
|  ID     |      start_date     |     end_date     |  status   | 
+---------+---------------------+------------------+-----------+ 
|  1      |   2017-12-09 03:23  | 2017-12-10 03:23 |      1    | 
+---------+---------------------+------------------+-----------+ 
| ...     |         ...         |       ...        |      1    | 
+---------+---------------------+------------------+-----------+ 
| 1000000 |   2017-12-22 15:12  | 2017-12-30 15:12 |      1    | 
+---------+---------------------+------------------+-----------+ 

当我插入一行时,我也创建了一个事件。 如果匹配结束,事件将状态更改为0。

CREATE EVENT test_event_increment_number
ON SCHEDULE AT end_date
ON COMPLETION NOT PRESERVE
DO
   UPDATE tblMatch SET status = 0 WHERE ID = increment_number;

如果 tblMatch 有1亿个匹配项: 它会影响服务器性能吗? 创造很多事件是不好或好主意?

3 个答案:

答案 0 :(得分:3)

只创建一个每天运行的事件,并关闭那天到期的匹配。

CREATE EVENT test_event
ON SCHEDULE AT 1 every day
STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY)
DO
   UPDATE tblMatch SET status = 0 WHERE end_date = CURRENT_DATE;

更新

如果您想要在一定时间内对事件进行计时,则可以将事件的频率更改为分钟级别,并在确定匹配是否需要关闭时使用分钟级别,或者完全删除状态字段并使用{{ 1}}字段的值与end_date进行比较,以确定事件是否已关闭。后者是一种更好的方式。

答案 1 :(得分:1)

我创建25个事件是不同的时间。过了一会儿,数据库将获取所有资源并重新启动。

   CREATE EVENT `auction_event_46709`
   ON SCHEDULE EVERY 5 MINUTE STARTS '2017-12-07 10:23:03'
   ON COMPLETION NOT PRESERVE ENABLE
   DO CALL auction_update_price(46709)

步骤:

CREATE PROCEDURE `auction_update_price`( IN p_id INT )
BEGIN
 DECLARE cur_price INT;
 DECLARE stp_price INT;
 DECLARE st_price INT;
 DECLARE str_price INT;
 SELECT current_price, step_price, stop_price, start_price INTO cur_price, stp_price, st_price, str_price FROM product_to_auction WHERE product_id = p_id;
 IF( cur_price - stp_price > st_price ) THEN
   UPDATE product_to_auction SET current_price = current_price - step_price WHERE current_price > stop_price AND product_id = p_id;
 ELSE
    UPDATE product_to_auction SET current_price = str_price WHERE product_id = p_id;
 END IF;
END

如何解决?

答案 2 :(得分:1)

根本不使用事件进行此类操作。当然不要使用很多活动。相反,请使用将end_date考虑在内的查询(或视图),并根据日期动态确定status值。例如,要按id检索特定项目,请执行此操作。

 SELECT id, start_date, end_date
        CASE WHEN end_date <= CURDATE() THEN 0  ELSE status END AS status
   FROM tblMatch
  WHERE id = something

此查询根据您运行查询的时刻返回表中的行以及status值。 (我进行了设置,因此status = 0的项目始终标记为已过期,请不要介意当前时间。)

如果您希望所有状态为1(意味着未过期)的项目执行此操作:

 SELECT id, start_date, end_date, 1 AS status
   FROM tblMatch
  WHERE end_date < CURDATE ()
    AND status = 1

如果您必须使用某个事件,则可以每天运行一次,午夜后的某个时间将所有过期行的status列重置为0,并使用类似的查询。

  UPDATE tblMatch SET status = 0 WHERE status = 1 AND end_date < CURDATE();

(我更喜欢在当地时间03:00之后不久运行每日更新查询。为什么?我位于美国,我们的夏令时转换已经完成,一年两次,当地时间02:00在03:00之后进行每日更新可确保他们在转换日仍能正常工作。)

要使这些查询有效,您需要(status, end_date)

上的复合索引