繁体   English   中英

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

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

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

btcaddress 和 txid 上都存在索引。

里面的数据是这样的: 在此处输入图片说明

我需要删除所有“可删除”的记录对。 一个例子以红色给出。 条件是:

  • txid 必须相同(可以有 2 个以上的记录具有相同的 txid)

  • vinvoutnr 必须相同

  • vin 必须不同(只能有 2 个值 0 和 1,所以 1 必须是 0 其他必须是 1)

在一个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;

或者我是否忘记了删除查询并尝试创建一个包含所有不可删除内容的新表,然后删除原始表?

对于此删除查询,数据库可以脱机。

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

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)的索引。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM