代码之家  ›  专栏  ›  技术社区  ›  Electro SoapBox

如何快速修剪大桌子?

  •  4
  • Electro SoapBox  · 技术社区  · 14 年前

    我目前有一个大约2000万行的MySQL表,我需要删减它。我想删除每一行 updateTime (插入时间戳)是一个多月前。我个人没有对表的顺序进行任何更改,因此数据应该按照插入的顺序进行,并且有一个 UNIQUE 输入两个字段, id

    4 回复  |  直到 5 年前
        1
  •  15
  •   Will Hartung    14 年前

    你能耽误多少时间?排得多大?你要删除多少?

    简单地说,删除行是对表执行的最昂贵的操作之一。总的来说这是件可怕的事情。

    如果您不必这样做,并且有足够的磁盘空间,并且查询不受表大小的影响(索引良好的查询通常忽略表大小),那么您就可以完全不用管了。

    否则的话,你就只能用好的ol删除了。

        2
  •  13
  •   Mark Byers    14 年前

    有两种方法可以删除大量行。首先是显而易见的方法:

    DELETE FROM table1 WHERE updateTime < NOW() - interval 1 month;
    

    第二种方法(稍微复杂一点)是创建一个新表并复制要保留的数据,截断旧表,然后将行复制回来。

    CREATE TABLE table2 AS
    SELECT * FROM table1 WHERE updateTime >= NOW() - interval 1 month;
    
    TRUNCATE table1;
    
    INSERT INTO table1
    SELECT * FROM table2;
    

    使用 TRUNCATE 比一个 DELETE 用一个 WHERE

        3
  •  0
  •   Chandrashekar Vijayarenu    11 年前

    我取消了查询(花了几个小时)

    然后分割删除。

    DELETE from table where id > XXXX limit 10000;
    DELETE from table where id > XXXX limit 10000;
    DELETE from table where id > XXXX limit 10000;
    DELETE from table where id > XXXX limit 10000;
    

    mysql> source /tmp/delete.sql 
    

    这要快得多。

        4
  •  0
  •   halfer Rajnish Kumar    7 年前

    实际上,即使不能使表长时间脱机,仍然可以使用“重命名表”技术来除去旧数据。

    rename table tableName to tmpTableName;
    create table tableName like tmpTableName;
    set @currentId=(select max(id) from tmpTableName);
    set @currentId=@currentId+1;
    set @indexQuery = CONCAT("alter table test auto_increment = ", @currentId);
    prepare stmt from @indexQuery;
    execute stmt;
    deallocate prepare stmt;
    

    启动写入表的进程。

    insert into tableName
    select * from tmpTableName;
    drop table;