写 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" 记录对。示例以红色给出。
条件是:
txid必须相同(相同txid的记录可以超过2条)
vinvoutnr 必须相同
vin 必须不同(只能有 2 个值 0 和 1,所以 1 必须是 0 其他必须是 1)
在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)
上建立索引。
我有一个 MySQL 数据库,只有 1 table: 字段是:blocknr(不唯一)、btcaddress(不唯一)、txid(不唯一)、vin、vinvoutnr、netvalue。
btcaddress 和 txid 上都有索引。
其中的数据如下所示:
我需要删除所有 "deletable" 记录对。示例以红色给出。 条件是:
txid必须相同(相同txid的记录可以超过2条)
vinvoutnr 必须相同
vin 必须不同(只能有 2 个值 0 和 1,所以 1 必须是 0 其他必须是 1)
在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)
上建立索引。