Eu tenho um banco de dados MySQL com apenas 1 mesa: Os campos são: blocknr (não exclusivo), btcaddress (não exclusivo), txid (não exclusivo), vin, vinvoutnr, netvalue.
existem índices em ambos btcaddress e txid.
Eu preciso eliminar todos os pares de registros "elimináveis". Um exemplo é dado no vermelho. As condições são:
txid deve ser o mesmo (não pode haver mais do que 2 fichas com a mesma txid)
vinvoutnr deve ser o mesmo
vin deve ser diferente (pode ter apenas dois valores 0 e 1, de modo que uma tem de ser 0 outro deve ser 1)
Em uma tabela de registros 36M, 33M sobre registros serão apagados.
Eu usei isso:
delete t1
from registration t1
inner join registration t2
where t1.txid=t2.txid and t1.vinvoutnr=t2.vinvoutnr and t1.vin<>t2.vin;
Ele funciona, mas leva 5 horas.
Talvez isso iria trabalhar muito (ainda não testado):
delete t1
from registration as t1, registration as t2
where t1.txid=t2.txid and t1.vinvoutnr=t2.vinvoutnr and t1.vin<>t2.vin;
Ou eu esquecer uma consulta de exclusão e tentar fazer uma nova tabela com todos os não-delatables e em seguida, solte o original?
Banco de dados pode estar off-line para esta consulta de exclusão.
Baseado em sua pergunta, você está excluindo a maioria das linhas na tabela. Isso é simplesmente muito caro. Uma abordagem melhor é para esvaziar a mesa e re-preenchê-lo:
create table temp_registration as
<query for the rows to keep here>;
truncate table registration;
insert into registration
select *
from temp_registration;
Sua lógica é um pouco difícil de seguir, mas acho que a lógica nas linhas para manter é:
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
);
Para um melhor desempenho, você quer um índice em registration(txid, vinvoutnr, vin)
.