簡體   English   中英

截斷條件

[英]Truncate with condition

truncate - >這會重置整個表,有沒有辦法通過truncate來重置特定的記錄/檢查條件。

例如:我想重置所有數據並在表格中保留最近30天。

謝謝。

不, TRUNCATE是全有或全無。 您可以執行DELETE FROM <table> WHERE <conditions>但這會失去TRUNCATE的速度優勢。

簡短的回答是否定的:MySQL 不會允許你添加一個WHERE子句的TRUNCATE語句。 這是MySQL關於TRUNCATE語句的文檔

但好消息是你可以(有點)解決這個限制。

使用DELETE簡單,安全,干凈但緩慢的解決方案

首先,如果表足夠小,只需使用DELETE語句(必須提到):

1. LOCK TABLE my_table WRITE;
2. DELETE FROM my_table WHERE my_date<DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. UNLOCK TABLES;

LOCKUNLOCK語句不是強制性的,但它們可以加快速度並避免潛在的死鎖。

不幸的是,如果你的表很大,這將非常慢......並且因為你正在考慮使用TRUNCATE語句,我想這是因為你的表很大。

所以這是使用TRUNCATE語句解決問題的一種方法:

使用TRUNCATE簡單,快速但不安全的解決方案

1. CREATE TABLE my_table_backup AS
      SELECT * FROM my_table WHERE my_date>=DATE_SUB(NOW(), INTERVAL 1 MONTH);
2. TRUNCATE my_table;
3. LOCK TABLE my_table WRITE, my_table_backup WRITE;
4. INSERT INTO my_table SELECT * FROM my_table_backup;
5. UNLOCK TABLES;
6. DROP TABLE my_table_backup;

不幸的是,如果其他進程同時在表中插入記錄,則此解決方案有點不安全:

  • 在步驟1和2之間插入的任何記錄都將丟失
  • TRUNCATE語句將AUTO-INCREMENT計數器重置為零。 因此,在步驟2和3之間插入的任何記錄都將具有低於舊ID的ID,甚至可能與在步驟4中插入的ID沖突(請注意,在步驟4之后, AUTO-INCREMENT計數器將返回到其正確的值) 。

不幸的是,無法鎖定表並截斷它。 但是我們可以(某種方式)使用RENAME解決這個限制。

使用TRUNCATE半簡單,快速,安全但嘈雜的解決方案

1. RENAME TABLE my_table TO my_table_work;
2. CREATE TABLE my_table_backup AS
     SELECT * FROM my_table_work WHERE my_date>DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. TRUNCATE my_table_work;
4. LOCK TABLE my_table_work WRITE, my_table_backup WRITE;
5. INSERT INTO my_table_work SELECT * FROM my_table_backup;
6. UNLOCK TABLES;
7. RENAME TABLE my_table_work TO my_table;
8. DROP TABLE my_table_backup;

這應該是完全安全且非常快的。 唯一的問題是其他進程會看到表my_table消失幾秒鍾。 這可能會導致在各處的日志中顯示錯誤。 所以這是一個安全的解決方案,但它“嘈雜”。

免責聲明 :我不是MySQL專家,所以這些解決方案實際上可能很糟糕。 我能提供的唯一保證就是它對我來說很好。 如果有專家可以評論這些解決方案,我將不勝感激。

作為對您問題的回答:“我想重置所有數據,並在表格中保留最近30天。”

你可以創建一個事件。 檢查https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html

例如:

CREATE EVENT DeleteExpiredLog
ON SCHEDULE EVERY 1 DAY
DO
DELETE FROM log WHERE date < DATE_SUB(NOW(), INTERVAL 30 DAY);

將在您的表中進行每日清理,保留最近30天的數據

您可以使用datapump簡單地使用查詢子句導出表,並使用table_exists_action = replace子句將其導回。 它會掉落並重新創建你的桌子,花費的時間更少。 請在實施前閱讀相關內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM