【问题标题】:The best way to delete 5K rows from Innodb table with 30M rows从具有 30M 行的 Innodb 表中删除 5K 行的最佳方法
【发布时间】:2011-05-19 07:46:06
【问题描述】:

表:

  • foreign_id_1
  • foreign_id_2
  • 整数
  • 日期1
  • 日期2
  • primary(foreign_id_1, foreign_id_2)

查询:delete from table where (foreign_id_1 = ? or foreign_id_2 = ?) and date2 < ?

无日期查询大约需要 40 秒。这太高了:(日期要长得多..

选项有:

  • create另一个表和insertselect,然后rename
  • 使用限制并多次运行查询
  • 拆分查询以运行 foreign_id_1 然后 foreign_id_2
  • 使用选择然后按单行删除

有没有更快的方法?


mysql> explain select * from compatibility where user_id = 193 or person_id = 193 \G
           id: 1
  select_type: SIMPLE
        table: compatibility
         type: index_merge
possible_keys: PRIMARY,compatibility_person_id_user_id
          key: PRIMARY,compatibility_person_id_user_id
      key_len: 4,4
          ref: NULL
         rows: 2
        Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where
1 row in set (0.00 sec)

mysql> explain select * from compatibility where (user_id = 193 or person_id = 193) and updated_at < '2010-12-02 22:55:33' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: compatibility
         type: index_merge
possible_keys: PRIMARY,compatibility_person_id_user_id
          key: PRIMARY,compatibility_person_id_user_id
      key_len: 4,4
          ref: NULL
         rows: 2
        Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where
1 row in set (0.00 sec)

【问题讨论】:

  • 请在您的查询中发布EXPLAIN 的结果。我的钱是因为索引不足。
  • 添加查询说明
  • 选项 3 和 4 的组合是一个不错的方法,前提是您的 SELECTS 足够快。 PK删除不会出错。 :)

标签: mysql performance innodb sql-delete large-data


【解决方案1】:

在你的WHERE 中有一个OR 会使 MySQL 不愿意(如果不是完全拒绝)在你的 user_id 和/或 person_id 字段上使用索引(如果有的话——显示 CREATE TABLE 会指出是否有)。

如果您可以添加索引(或修改现有索引,因为我正在考虑复合索引),我可能会添加两个:

ALTER TABLE compatibility 
ADD INDEX user_id_updated_at (user_id, updated_at),
ADD INDEX persona_id_updated_at (person_id, updated_at);

相应地,假设DELETE 的行不必被自动删除(即同时发生)。

DELETE FROM compatibility WHERE user_id = 193 AND updated_at < '2010-12-02 22:55:33';

DELETE FROM compatibility WHERE person_id = 193 AND updated_at < '2010-12-02 22:55:33';

【讨论】:

  • 即使删除必须是原子的,这可以通过 InnoDB 事务来完成。
  • @桑尼 -- 确实如此。重新阅读他的帖子,最后一个想法'使用选择然后按单行删除',表明他会没事的。
【解决方案2】:

目前数据量为 4000 万(+33%),并且还在快速增长。所以我开始寻找其他一些无 sql 的解决方案。

谢谢。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多