处理没有索引的非常大的表

时间:2017-10-31 15:32:14

标签: mysql mysql-5.7

我有一个非常大的表,有20-30万行,每次由提供我无法控制的数据的系统更新时都会被完全覆盖。

  • 表格未按特定顺序排序。
  • 表中的行是唯一的,没有列的子集可以保证具有唯一值。

我是否有办法在此表上运行SELECT查询后跟DELETE查询并且具有固定限制,而无需触发任何昂贵的排序/索引/分区/比较,同时确保我不删除前一个选择未涵盖的行。

1 个答案:

答案 0 :(得分:0)

我认为你要求:

SELECT * FROM MyTable WHERE x = 1 AND y = 3;

DELETE * FROM MyTable WHERE NOT (x = 1 AND y = 3);

换句话说,对于您在第一个查询中使用的相同搜索表达式使用NOT来获取行集的补码。这适用于大多数表达式,除非您的某些术语返回NULL。

如果没有索引,那么SELECT和DELETE都会产生表扫描,但没有排序或临时表。

重新评论:

是的,除非您使用ORDER BY,否则您无法保证所返回行的顺序。从技术上讲,存储引擎可以任意顺序返回行。

实际上,你会发现InnoDB至少以一种可预测的顺序返回行:它以某种索引顺序读取行。即使您的表没有定义键或索引,每个 InnoDB表也会存储为聚簇索引,即使它必须为generate an internal key called GEN_CLUST_ID behind the scenes。这将是InnoDB返回行的顺序。

但你不应该依赖它。内部实施不是合同,明天可能会改变。

我可以提供另一个建议:

CREATE TABLE MyTableBase (
  id INT AUTO_INCREMENT PRIMARY KEY,
  A INT,
  B DATE,
  C VARCHAR(10)
);

CREATE VIEW MyTable AS SELECT A, B, C FROM MyTableBase;

使用上面的表和视图,您的外部进程可以相信它覆盖MyTable中的数据,但实际上它将存储在具有附加主键列的基表中。这是您可以用来执行SELECT和DELETE语句,并通过主键列排序,以便您可以正确控制它。