我有一个非常大的表,有20-30万行,每次由提供我无法控制的数据的系统更新时都会被完全覆盖。
我是否有办法在此表上运行SELECT
查询后跟DELETE
查询并且具有固定限制,而无需触发任何昂贵的排序/索引/分区/比较,同时确保我不删除前一个选择未涵盖的行。
答案 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语句,并通过主键列排序,以便您可以正确控制它。