Sql 带条件截断

Sql 带条件截断,sql,mysql,truncate,Sql,Mysql,Truncate,truncate->重置整个表,是否有办法通过truncate重置特定记录/检查条件 例如:我想重置所有数据并将最后30天保留在表中 谢谢。不,TRUNCATE是全部还是全部。您可以从WHERE执行DELETE操作,但这会失去TRUNCATE的速度优势。简短的回答是no:MySQL不允许您在TRUNCATE语句中添加WHERE子句。下面是关于TRUNCATE语句的内容 但好消息是,你可以(多少)绕过这个限制 使用删除 1. CREATE TABLE my_table_backup AS

truncate->重置整个表,是否有办法通过truncate重置特定记录/检查条件

例如:我想重置所有数据并将最后30天保留在表中


谢谢。

不,
TRUNCATE
是全部还是全部。您可以从WHERE执行
DELETE操作,但这会失去
TRUNCATE

的速度优势。简短的回答是no:MySQL不允许您在
TRUNCATE
语句中添加
WHERE
子句。下面是关于
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. 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;
首先,如果表足够小,只需使用
DELETE
语句(必须提及):

不幸的是,如果其他进程同时在表中插入记录,则此解决方案有点不安全:

  • 在步骤1和步骤2之间插入的任何记录都将丢失
  • TRUNCATE
    语句将
    自动递增
    计数器重置为零。因此,在步骤2和步骤3之间插入的任何记录的ID都将低于旧ID,甚至可能与步骤4中插入的ID冲突(请注意,
    自动递增
    计数器将在步骤4后返回到其正确值)
不幸的是,不可能锁定表并截断它。但我们可以(以某种方式)使用
重命名
来克服这个限制

使用
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. 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;
这应该是完全安全和相当快的。唯一的问题是其他进程会看到table
my_table
消失几秒钟。这可能会导致日志中到处显示错误。因此,这是一个安全的解决方案,但它是“嘈杂的”


免责声明:我不是MySQL专家,所以这些解决方案实际上可能很糟糕。我能提供的唯一保证是它们对我来说很好。如果有专家能对这些解决方案发表意见,我将不胜感激。

您只需使用datapump将带有查询子句的表导出,然后使用table\u exists\u action=replace子句将其导入。它将删除并重新创建您的表,所需时间非常少。在实施之前,请阅读相关内容。

作为对您问题的回答: “我想重置所有数据,并在表中保留最后30天。”

您可以创建一个事件。检查

例如:

CREATE EVENT DeleteExpiredLog
ON SCHEDULE EVERY 1 DAY
DO
DELETE FROM log WHERE date < DATE_SUB(NOW(), INTERVAL 30 DAY);
创建事件DeleteExpiredLog
按计划每1天
做
从日志中删除日期

将在您的表中运行每日清理,保持最近30天的数据可用

谢谢,假设存在这种情况,我如何以优化的方式保留最近10天的数据并删除其余的数据(例如,该表有1000万条记录)。TRUNCATE的速度是因为它不会从speed TRUNCATE写入logsApart还可以释放磁盘空间,但是删除保留磁盘空间。这是一个很好的答案,也是解决这些限制的好方法。谢谢。事实上,如果表被分割成多个分区,那么您可以只截断选定的分区,这样就不会拖出整个表。