I have a MySQL database with one big table in it. After a while, it becomes too full and performance degrades. Every Sunday, I want to delete rows whose last update is older than a certain number of days ago.
How do I do that?
Make a Scheduled Event to run your query every night. Check out Event Scheduler as well.
CREATE EVENT `purge_table` ON SCHEDULE
EVERY 1 DAY
ON COMPLETION NOT PRESERVE
ENABLE
COMMENT ''
DO BEGIN
DELETE FROM my_table WHERE my_timestamp_field <= now() - INTERVAL 5 DAY
END
What is the table design? Do you have a column with a timestamp?
Assuming you do, you could use that timestamp value with a datediff(your_date,CURDATE()) in a delete command.
Delete from table where datediff(date_col, CURDATE ()) > your_num_days.
Self Answer
Make a web server that sends the following SQL to the database every weekend:
DELETE FROM table WHERE timestamp < DATE_SUB(NOW(), INTERVAL 7 DAY);
or
DELETE FROM table
WHERE timestamp < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 7 DAY))
I might need locking to prevent accumulation of jobs, like so:
DELIMITER //
CREATE EVENT testlock_event ON SCHEDULE EVERY 2 SECOND DO
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
DO RELEASE_LOCK('testlock_event');
END;
IF GET_LOCK('testlock_event', 0) THEN
-- add some business logic here, for example:
-- insert into test.testlock_event values(NULL, NOW());
END IF;
DO RELEASE_LOCK('testlock_event');
END;
//
DELIMITER ;
Final answer:
CREATE EVENT `purge_table` ON SCHEDULE
EVERY 1 DAY
ON COMPLETION NOT PRESERVE
ENABLE
COMMENT ''
DO BEGIN
IF GET_LOCK('purge_table', 0) THEN
DELETE FROM table WHERE timestamp < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 7 DAY));
END;
Maybe you can provide more information on how you are pushing the data to the DB and how you are working on the DB in general? Therefore we can help you and don't have to struggle with the dark...
I'll provide an easy solution: It's kind of workaround, but works:
Everytime you touch the data you update a time stamp in the updated rows.
Therefore you could easily filter them out every sunday.
UPDATE
The answer, the author provided by himself, was discussed at Stackoverflow and seems not to work in exactly that way, compare the discussion.
Related
DELIMETER $$
CREATE EVENT loan_balance ON SCHEDULE EVERY '1' MONTH AND '5' DAYS
DO BEGIN UPDATE users SET loan_balance = total_loans_collected -
total_loans_paid;
END$$
DELIMETER;
Hello! I want to update this table on the 5th of every month and not just monthly. The "AND '5' DAYS isn't making it work.
You need a slightly different ON SCHEDULE phrase.
AT '2018-04-01 03:01' + INTERVAL 5 DAY EVERY MONTH
fires your event at 03:01 local time on the fifth day of every month.
03:01 is a good time for a scheduled job because it doesn't get messed up by standard-time / daylight-time switchovers.
Instead of using a trigger to update the loan_balance column, you can turn it into a generated column.
ALTER TABLE users MODIFY COLUMN loan_balance INT GENERATED ALWAYS AS
(total_loans_collected - total_loans_paid) STORED;
Unless I'm missing something, I believe this is the most optimal approach, and it is certainly easier to maintain.
I'm wondering if there is any way to schedule an update where I update a tables data on expiration of the old one.
E.g. John Smith has an active service at Company X, but wants to upgrade the service. However, due to restrictions to his current agreement the new service doesn't take effect until X days.
Is there any way to store the new data and update it at the end of a month in MySQL? If yes, would this require me to have another table with the new order data stored?
Often this requirement for changing things at future times is handled by placing start_date and end_date columns in your services table.
Then you can find presently active service rows with
SELECT user_id, whatever, whatelse
FROM services
WHERE (start_date IS NULL OR start_date <= NOW())
AND (end_date IS NULL OR end_date > NOW());
You can, if you wish, create a view called active_services automatically filtering the services table for currently active services.
CREATE VIEW active_services AS
SELECT *
FROM services
WHERE (start_date IS NULL OR start_date <= NOW())
AND (end_date IS NULL OR end_date > NOW());
Note -- in this design end_date contains not the last moment the service is active but the first moment it becomes inactive. If end_date is null the service continues to be active.
To change a service or user_id at the beginning of next month you do these two operations:
UPDATE service
SET end_date = LAST_DAY(NOW()) + INTERVAL 1 DAY
WHERE user_id = <<user id you wish to change >>
INSERT INTO service (start_date, user_id, whatever, whatelse)
VALUES (LAST_DAY(NOW()) + INTERVAL 1 DAY,
<<user id you wish to change >>,
<<whatever>>,
<<whatelse>>;
Then, when next month arrives the active_services view returns the new service. This is much more robust than relying on a precisely timed monthly job. If you do a monthly job, it can run anytime. It simply cleans up expired services.
You can use MySQL events to run particular jobs at appointed times. (But some shared MySQL systems don't let you use events.)
Interestingly mysql has event schedulers have a look at the documentation.
below is an example of a minimal CREATE EVENT statement:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
The previous statement creates an event named myevent. This event executes once—one hour following its creation—by running an SQL statement that increments the value of the myschema.mytable table's mycol column by 1.
If yes, would this require me to have another table with the new order data stored
I am not sure if you need another table or so...it purely depends on how you want it to be one
I have a table in my MYSQL database called sale as shown below:
I want to auto delete the sales that are 3 days old and not validated,
I create event but unfortunately it doesn't work here's my code :
CREATE EVENT `delete_sale` ON SCHEDULE EVERY 1 HOUR DO DELETE FROM sale WHERE sale.is_validated = 0 and sale.date < DATE_SUB(NOW(), INTERVAL 3 DAY)
My best guess is that your event is working, but it's only firing once then deactivating. To fix that, you should add the "ON XOMPLETION PRESERVE" line. Another possibility is that it's not loading properly because it can't quite parse your event code. To really hold MySQL's hand with this, try treating it like a multi statement event, changing the delimiter and adding BEGIN and END. Something like this:
DELIMITER &&
CREATE EVENT `delete_sale`
ON SCHEDULE EVERY 1 HOUR
ON COMPLETION PRESERVE
DO
BEGIN
DELETE FROM sale WHERE sale.is_validated = 0 and sale.date < DATE_SUB(NOW(), INTERVAL 3 DAY);
END &&
DELIMITER ;
the problem resolved by enabling event_scheduler with the following query SET GLOBAL event_scheduler = ON;
I want to create table with name "dynamicdate" in which first column name is "datecolumn" which will contain 15 rows i.e. first row should represent today's date for example 08/08/2017 and following column shows subsequent date for example, 08/09/2017, 08/10/2017 till 15th row contains 08/23/2017.
Question 1: How do I fill 15 rows in a column with consecutive date simultaneously.
Now, for example date becomes 08/09/2017 (because august 8 is over) is the today'date and 08/24/2017 is date of 15th day.
Question 2: How do i update database everyday dynamically i.e. without querying database.
This you can do by creating a job. Every morning or night schedule this Job.
A job will execute this procedure "p_Update_dynamicdate".
create proc dbo.p_Update_dynamicdate
as
Begin
Declare #date as datetime, #count as int
set #date =getdate()
set #count =1
truncate table dynamicdate --Delete old data
while #count<=15
Begin
insert into dynamicdate(Ddate)
select Dateadd(d,#count,getdate())
set #count=#count+1
End
End
Solution to problem #1 :
Already solved on StackOverflow :
MySQL - How can I add consecutive dates to many existing records?
Solution to problem #2 :
Please look at Schedule and events on MySql documentation :
https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html
syntax: CREATE EVENT my_event
ON SCHEDULE
EVERY 1 DAY
STARTS '2014-04-30 00:20:00' ON COMPLETION PRESERVE ENABLE
DO
# Your Update query
Please refer to below links for similar problem solution :
https://dba.stackexchange.com/questions/64208/scheduling-an-event-every-day-at-a-given-time
How to schedule a MySQL query?
I am writing a MySQL Database and I wish to do the title within the MySQL database itself via Events if possible. I am updating the database via a Windows Service written in VB.net and have no desire to do the below via a separate 'server control' type program.
Basically, I have written the below in to the Database, but it doesn't quite do what I want:
Create Event MachineOffline
On
SCHEDULE Every 2 Minute
Do
UPDATE maindb.monitortable SET Online='1';
I would like it to say something like the below:
Create Event MachineOffline
On
SCHEDULE Every 2 Minute
Do
IF **RowX updated < 2 minutes ago** then
UPDATE Database.Table SET Online='0' where RowX(ID);
I have no idea how to achieve this hence my question to everyone. I have no desire to create
If you give your Database.Table an extra column, lets say, last_updated timestamp, you can then update it like so:
update Database.Table
set online=0, last_updated = now()
where last_updated <= now() - interval 2 minute
and online=1