【问题标题】:Delete every other rows except the rows number in a given list删除除给定列表中的行号之外的所有其他行
【发布时间】:2010-12-17 06:16:15
【问题描述】:

所以基本上这就是我想要做的:我有一个帐户表,我有一个 acct_id 列表:(3、24、515、6326、17),假设我表中有大约 100,000 个帐户,最多的是什么删除除给定列表中具有 account_id 的行之外的所有其他行的有效方法?

我想出了类似的东西:

delete from account where acct_id is not in (3, 24, 515, 6326, 17);

我听说这个查询很慢,因为它是递归的什么的。考虑一下我拥有的行数,那会非常慢。有什么更好的方法来做到这一点?

【问题讨论】:

  • 你有表关系——从其他表到这个表的外键吗?您(计划)在该表上有多少索引?这些可以极大地改变答案:即删除表可能不是选项,或者简单的 DELETE 性能将与棘手的方式相同。知道你在优化什么:它可能没有被破坏。
  • @fei 我知道这个问题很老了,但我可以知道你为什么或在哪里听说你的查询很慢吗?

标签: mysql database delete-row large-data-volumes


【解决方案1】:
从表中删除 where not acct_id in (3, 24, 515, 6326, etc.);

根据数据库风格、索引、分布式与否等,这可能需要大量工作。即使在全日志数据库中也能有效工作的替代方法是:

create table2 temp as /* 从要保留的行创建新表 */ 选择 * 从表 其中 acct_id 在(3、24、515、6326 等); 掉落表; /* 丢弃表 */ create table as /* 复制新表以重命名 */ 从表2中选择*; 删除表2; /* 删除临时表 */

【讨论】:

  • 这似乎与我想出的解决方案几乎相同...想多解释一下这对大量数据有何影响?
  • 我写答案的时候没有看到SQL语句。你后来添加的吗?
  • 我之前没有把它放在代码标签中。但你建议的替代方案似乎很有希望。谢谢。
  • 由于他使用的是MySQL,最后一步可以是RENAME TABLE table2 TO table;
  • 当心删除表的副作用:需要重新创建索引和其他约束。我更喜欢使用 TRUNCATE TABLE。在下面发布了解决方案。
【解决方案2】:

您的查询对我来说似乎很好,但如果您想优化您的查询,请查看Explain

【讨论】:

    【解决方案3】:

    如果您在 acct_id 上有一个索引,我看不出您的查询应该慢的任何原因。 据我所知

    in (3, 24, 515, 6326, 17)
    

    只是

    的语法糖
    acct_id != 3 AND acct_id != 24 ...
    

    应该足够快。

    【讨论】:

      【解决方案4】:

      不特定于 MySQL,但删除通常相对昂贵,因为它们需要引擎执行一系列选择以确保删除正确的记录以及实际删除。您还会在事务日志中添加大量事务(当然取决于引擎和设置)。

      如果您只想保留一小部分记录,而要丢弃大量记录,那么您可以通过作弊获得更快的性能...

      您复制要保留的记录并删除或截断表格,然后重新添加“管理员”。

      【讨论】:

        【解决方案5】:

        我的解决方案是避免 DELETE 并使用 TRUNCATE 表,因为当您删除数据库时会执行两个操作。删除记录并将其写入回滚段。

        当然,这意味着截断时不会回滚。

        -- copy the few records into a temp table
        select into temp 
         select * from account
         where acct_id in (3, 24, 515, 6326, 17);
        
        -- truncate is super fast
        truncate table account;
        
        -- put back the few records
        insert into account select * from temp;
        
        drop table temp;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-22
          • 2010-09-27
          • 2022-01-26
          • 2020-12-03
          • 1970-01-01
          • 1970-01-01
          • 2015-03-27
          相关资源
          最近更新 更多