我有一张表 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亿个匹配项: 它会影响服务器性能吗? 创造很多事件是不好或好主意?
答案 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)