写 SQL delete 语句的最佳方式,删除成对的记录

Best way to write SQL delete statement, deleting pairs of records

我有一个 MySQL 数据库,只有 1 table: 字段是:blocknr(不唯一)、btcaddress(不唯一)、txid(不唯一)、vin、vinvoutnr、netvalue。

btcaddress 和 txid 上都有索引。

其中的数据如下所示:

我需要删除所有 "deletable" 记录对。示例以红色给出。 条件是:

在table条36M条记录中,约有33M条记录将被删除。

我用过这个:

delete t1 
from registration t1 
inner join registration t2 
where t1.txid=t2.txid and t1.vinvoutnr=t2.vinvoutnr and t1.vin<>t2.vin;

有效,但需要 5 个小时。

也许这也行(尚未测试):

delete t1 
from registration as t1, registration as t2 
where t1.txid=t2.txid and t1.vinvoutnr=t2.vinvoutnr and t1.vin<>t2.vin;

或者我是否忘记删除查询并尝试创建一个包含所有非延迟table 的新 table 然后删除原始查询?

对于此删除查询,数据库可能处于脱机状态。

考虑到您希望删除大部分数据,听起来最简单的方法是使用正确的数据创建一个新的 table,然后删除原来的 table建议。否则,ADyson 对 JOIN 查询的更正可能有助于缓解性能问题。

根据您的问题,您将删除 table 中的大部分行。那真是太贵了。更好的方法是清空 table 并重新填充它:

create table temp_registration as
    <query for the rows to keep here>;

truncate table registration;

insert into registration
    select *
    from temp_registration;

您的逻辑有点难以理解,但我认为要保留的行的逻辑是:

select r.*
from registration r
where not exists (select 1
                  from registration r2
                  where r2.txid = r.txid and
                        r2.vinvoutnr = r.vinvoutnr and
                        r2.vin <> r.vin
                 );

为了获得最佳性能,您需要在 registration(txid, vinvoutnr, vin) 上建立索引。